天道酬勤,学无止境

Sympy:删除多项式中的高阶项(Sympy: Drop higher order terms in polynomial)

问题

使用 Sympy,假设我们有一个表达式 f,它是符号“x”(可能还有其他符号)的多项式。

我想知道是否有一种有效的方法可以删除大于某个整数 n 的 f 阶中的所有项。

作为一种特殊情况,我有一个非常复杂的函数,但我只想将项保持在 x 中的二阶。 这样做的有效方法是什么?

显而易见的,不是非常有效的方法是对于每个小于 n 的 m,取 m 个导数并将 x 设置为 0 以获得 x^m 的系数。 我们以这种方式获得每个系数,然后重建多项式。 但采取衍生品并不是最有效的方式。

回答1

一种简单的方法是将O(x**n)到表达式中,例如

In [23]: x + x**2 + x**4 + x**10 + O(x**3)
Out[23]:
     2    ⎛ 3⎞
x + x  + O⎝x ⎠

如果您想稍后删除它,请使用removeO方法

In [24]: (x + x**2 + x**4 + x**10 + O(x**3)).removeO()
Out[24]:
 2
x  + x

您还可以使用series对表达式进行级数扩展。 这里的区别在于如果非多项式项出现在表达式中时的行为:

In [25]: x + sin(x) + O(x**3)
Out[25]:
              ⎛ 3⎞
sin(x) + x + O⎝x ⎠

In [26]: (x + sin(x)).series(x, 0, 3)
Out[26]:
       ⎛ 3⎞
2⋅x + O⎝x ⎠
回答2

如果您查看多项式模块文档:

http://docs.sympy.org/latest/modules/polys/reference.html

有很多方法可以解决这个问题,具体取决于您的具体情况。 几种不同的工作方式:

使用.coeffs()

>>> f = 3 * x**3 + 2 * x**2 + x * y + y**3 + 1
>>> order = 2

>>> coeffs = Poly(f, x).coeffs()
>>> f_new = sum(x**n * coeffs[-(n+1)] for n in range(order+1)) # the +1 is to get 0th order
>>> f_new
2*x**2 + x*y + y**3 + 1

或者,您可以迭代.all_terms()项目:

>>> all_terms = Poly(f, x).all_terms()
>>> sum(x**n * term for (n,), term in all_terms() if n <= order)

模块中有很多操作函数,您应该能够直接使用表达式而不是进行计算/取导数等。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Sympy: Drop higher order terms in polynomial
    Using Sympy, say we have an expression f, which is a polynomial of the Symbol "x" (and of potentially other symbols). I would like to know what if there is an efficient way to drop all terms in f of order greater than some integer n. As a special case I have a very complicated function but i want to only keep terms up to 2nd order in x. What's the efficient way to do this? The obvious, not-very-efficient way to do it would be for each m less than n, take m derivatives and set x to 0 to obtain the coefficient of x^m. We obtain each coefficient this way then reconstruct the polynomial. But
  • C/C++ 中的导数?(Derivatives in C/C++?)
    问题 我有一些表达式,例如x^2+y^2 ,我想用于一些数学计算。 我想做的一件事是取表达式的偏导数。 因此,如果f(x,y) = x^2 + y^2那么f相对于x的部分将是2x ,相对于y的部分将是2y 。 我使用有限差分方法编写了一个极小的函数,但是我遇到了很多浮点精度问题。 例如,我最终得到1.99234而不是2 。 是否有任何支持符号微分的库? 还有其他建议吗? 回答1 我已经用几种不同的语言实现了这样的库,但不幸的是不是 C。如果你只处理多项式(和、积、变量、常数和幂),这很容易。 触发功能也不错。 任何更复杂的事情,你可能最好花时间掌握其他人的图书馆。 如果您决定自己动手,我有一些建议可以简化您的生活: 使用不可变数据结构(纯函数式数据结构)来表示表达式。 使用 Hans Boehm 的垃圾收集器为您管理内存。 要表示线性和,请使用有限映射(例如,二叉搜索树)将每个变量映射到其系数。 如果您愿意将 Lua 嵌入您的 C 代码并在那里进行计算,我已将我的 Lua 代码放在 http://www.cs.tufts.edu/~nr/drop/lua。 更好的功能之一是它可以采用符号表达式,对其进行微分,并将结果编译到 Lua 中。 你当然会发现没有任何文件:-( 回答2 如果您正在进行数值微分(“在x = x0处评估f(x)的导数”)并且您事先知道您是方程(即,不是用户输入)
  • Sympy中的多元泰勒近似(Multivariate Taylor approximation in sympy)
    问题 我的目标是使用sympy编写sympy ,其中 使用尽可能多的内置代码, 计算两个变量的给定函数的截断泰勒逼近返回不包含Big-O-remainder项的结果,例如,在sin(x)=x - x**3/6 + O(x**4) 。 这是我到目前为止尝试过的: 方法1 天真的,对于每个变量,它只能对series命令进行两次组合,不幸的是,这是行不通的,如本例所示的函数sin(x*cos(y)) : sp.sin(x*sp.cos(y)).series(x,x0=0,n=3).series(y,x0=0,n=3) >>> NotImplementedError: not sure of order of O(y**3) + O(x**3) 方法2 根据这篇文章,我首先写了一维泰勒近似值: def taylor_approximation(expr, x, max_order): taylor_series = expr.series(x=x, n=None) return sum([next(taylor_series) for i in range(max_order)]) 用一维示例检查它可以正常工作 mport sympy as sp x=sp.Symbol('x') y=sp.Symbol('y') taylor_approximation(sp.sin(x*sp.cos(y
  • 加速SymPy中符号行列式的计算(Speeding up computation of symbolic determinant in SymPy)
    问题 我有一个 4x4 矩阵A ,在它的每个条目中都有相当长但简单的符号表达式。 大约涉及 30 个不同的符号。 “简单”是指仅使用加法/减法、乘法/除法和整数幂来组合这些符号。 “长”是指如果我打印出矩阵,它可以覆盖三到四个屏幕。 我需要这个矩阵的行列式。 或者,更具体地说,我知道行列式是一个特定符号中的四阶多项式,我需要这个多项式的系数。 A.det()在运行数小时后不会终止,所以我需要一种不同的方法。 有任何想法吗? 到目前为止,我已经尝试在A每个元素上抛出各种simplify函数,但没有成功。 是否有一些策略可以让 SymPy 知道我的表达式的简单结构,或者我知道结果是其中一个符号的多项式? 回答1 也许它可以为 4x4 行列式创建一般表达式 In [30]: A = Matrix(4, 4, symbols('A:4:4')) In [31]: A Out[31]: ⎡A₀₀ A₀₁ A₀₂ A₀₃⎤ ⎢ ⎥ ⎢A₁₀ A₁₁ A₁₂ A₁₃⎥ ⎢ ⎥ ⎢A₂₀ A₂₁ A₂₂ A₂₃⎥ ⎢ ⎥ ⎣A₃₀ A₃₁ A₃₂ A₃₃⎦ In [32]: A.det() Out[32]: A₀₀⋅A₁₁⋅A₂₂⋅A₃₃ - A₀₀⋅A₁₁⋅A₂₃⋅A₃₂ - A₀₀⋅A₁₂⋅A₂₁⋅A₃₃ + A₀₀⋅A₁₂⋅A₂₃⋅A₃₁ + A₀₀⋅A₁₃⋅A₂₁⋅A₃₂ - A₀‚
  • 在python中派生数学函数[关闭](Deriving a mathematical function in python [closed])
    问题 很难说出这里问的是什么。 这个问题模棱两可、含糊不清、不完整、过于宽泛或言辞激烈,无法以目前的形式合理回答。 如需帮助澄清此问题以便重新打开它,请访问帮助中心。 8 年前关闭。 这里的初学者程序员希望编写一个可以简单地推导出数学函数的函数。 该函数应该像这样运行: f(x) = x ** 2 + 2 * x <--- 用户输入 f'(x) = 2 * x + 2 我知道有 Wolfram 和 Maple,但我想编写自己的实际衍生程序。 我想知道这是否可能。 回答1 这显然是可能的,因为有很多程序可以进行符号微分。 话虽如此,这不是微不足道的。 对于上面的简单示例,您需要编写一个解析器: 拆分多项式的每一项解析项并将其分解为系数、变量和指数应用幂律将输出串在一起 那只会处理这种非常基本的衍生类型——没有链式规则、乘积规则等,你必须分别实现它们中的每一个。 所以是的,绝对可行,但也很重要。 回答2 这称为符号差异。 您需要将方程解析为表达式和运算树,然后将正常的微分规则(来自微积分 I)应用于树。 回答3 当然你可以花几天时间编写自己的微分程序(幸好微分很简单),但如果这不是练习,你实际上可以使用现成的东西,例如你可以使用 sympy: import sympy x = sympy.Symbol('x') sympy.diff(x**2+2*x, x) # return: 2*x
  • 强制SymPy保持条款的顺序(Force SymPy to keep the order of terms)
    问题 我有以下代码: from sympy import * init_printing() x,y = symbols('x y') u = Function('u')(x,y) ux,uy,uxx,uxy,uyy = symbols("u_x u_y u_xx u_xy u_yy") mainEvaluation = uxx - 2*sin(x)*uxy - (cos(x) ** 2) * uyy - 2*ux + (2 - cos(x) + 2*sin(x) )*uy 并且当print(mainExpression)的输出是 -2*u_x + u_xx - 2*u_xy*sin(x) + u_y*(2*sin(x) - cos(x) + 2) - u_yy*cos(x)**2 问题是:我想要变量的原始顺序。 u_xx - 2*u_xy*sin(x) - u_yy*cos(x)**2 - 2*u_x + u_y*(2*sin(x) - cos(x) + 2) 所有这些都是在IPython Notebook中完成的。 有什么方法可以保持秩序? 回答1 可悲的是,SymPy无法跟踪输入顺序(请参阅我在对该问题的评论中链接的另一个问题)。 您可以定义自己的排序函数,以便根据需要对表达式进行排序,但是由于无法保存信息,因此无法完全按照输入的顺序对它们进行排序。 回答2
  • 在Sympy中隔离多元多项式的一个系数的最佳方法(Best way to isolate one coefficient of a multivariate polynomial in sympy)
    问题 我有一个多元多项式(在一般情况下,它包含许多变量),其系数列出了一些需要读取的数据,但是看起来sympy并没有提供一种很好的方法。 collect函数似乎是正确的主意,但是当您将其与多个变量一起使用时,它实际上并没有为您提供单独的单项式,而是取决于列出变量顺序的奇怪的单项式分组。 有人知道这样做的方法吗? 回答1 多项式模块的文档列出了许多处理系数的方法。 例如: >>> import sympy >>> x,y,z = sympy.symbols('x,y,z') >>> p = sympy.poly((x+2*y-z)**3) >>> p.coeffs() [1, 6, -3, 12, -12, 3, 8, -12, 6, -1] 这些是按字典顺序的非零系数。 要按匹配顺序查看单项式,请使用 >>> p.monoms() [(3, 0, 0), (2, 1, 0), (2, 0, 1), (1, 2, 0), (1, 1, 1), (1, 0, 2), (0, 3, 0), (0, 2, 1), (0, 1, 2), (0, 0, 3)] 要获取特定单项式的系数,请使用 >>> p.coeff_monomial(x**2*y) 6 回答2 列出多项式的单项式,以便生成器出现(并且该顺序在用户的控制下): >>> from sympy import Poly >>>
  • 任意阶多项式的函数(首选符号方法)(Function for polynomials of arbitrary order (symbolic method preferred))
    问题 我从我的数据中找到了多项式系数: R <- c(0.256,0.512,0.768,1.024,1.28,1.437,1.594,1.72,1.846,1.972,2.098,2.4029) Ic <- c(1.78,1.71,1.57,1.44,1.25,1.02,0.87,0.68,0.54,0.38,0.26,0.17) NN <- 3 ft <- lm(Ic ~ poly(R, NN, raw = TRUE)) pc <- coef(ft) 所以我可以创建一个多项式函数: f1 <- function(x) pc[1] + pc[2] * x + pc[3] * x ^ 2 + pc[4] * x ^ 3 例如,取一个导数: g1 <- Deriv(f1) 如何创建一个通用函数,以便不必为每个新的多项式次数NN重写它? 回答1 我最初的答案可能不是你真正想要的,因为它是数字而不是象征性的。 这是象征性的解决方案。 ## use `"x"` as variable name ## taking polynomial coefficient vector `pc` ## can return a string, or an expression by further parsing (mandatory for `D`) f <- function (pc, expr =
  • 将因子表达式表达为矩阵系数?(Factor sympy expression to matrix coefficients?)
    问题 我试图勤于阅读文档,而且空无一人。 我正在尝试分解或消除矩阵形式的表达式中的术语。 我的问题似乎与多项式因式分解不同(因为我计划实现函数phi(x,y,z) = a_1 + a_2*x + a_3*y + a_4*z ) import sympy from sympy import symbols, pprint from sympy.solvers import solve phi_1, phi_2, x, a_1, a_2, L = symbols("phi_1, phi_2, x, a_1, a_2, L") #Linear Interpolation function: phi(x) phi = a_1 + a_2*x #Solve for coefficients (a_1, a_2) with BC's: phi(x) @ x=0, x=L shape_coeffs = solve([Eq(phi_1, phi).subs({x:0}), Eq(phi_2, phi).subs({x:L})], (a_1, a_2)) pprint(shape_coeffs) #Substitute known coefficients phi = phi.subs(shape_coeffs) pprint(phi) 这可以按预期工作,但是,我想将其分解为矩阵形式,其中:
  • C++中的符号计算(symbolic computation in C++)
    问题 我需要在 C++ 中进行分析集成。 例如,我应该整合这样的表达式: exp[I(xy)] , I是一个虚数。 我怎样才能在 C++ 中做到这一点? 我试过 GiNaC,但它只能对多项式进行积分。 我也尝试过 SymbolicC++。 它可以集成sine 、 cosine或exp(x)和ln(x)等ln(x) ,但它不是很强大。 例如,它不能对x*ln(x)进行积分,而x*ln(x)可以通过使用 Mathematica 或分部积分很容易获得。 是否有任何其他工具或库可以进行符号计算,例如 C++ 中的分析集成? 回答1 如果您需要进行符号集成,那么您可能不会比在 mathematica 或 maxima 中运行它更快——它们已经用(类似)C++ 编写了。 因此,除非您的方程有一个非常具体的公式,您可以以 Mathematica 或 Maxima 无法利用的方式加以利用,否则您可能不走运——至少您不会从现成的图书馆。 如果您需要进行数值求解,您可能有理由编写自己的代码来提高速度。 (我知道我是为生成偏微分方程的数值解而做的)。 回答2 我所知道的其他进行符号计算的 C++ 库是 SymEngine (https://github.com/symengine/symengine) 食人鱼 (https://github.com/bluescarni/piranha)
  • Enforce custom ordering on Sympy print
    SymPy does a wonderful work keeping track of all the operations I do to my symbolic expressions. But a the moment of printing the result for latex output I would like to enforce a certain ordering of the term. This is just for convention, and unfortunately that convention is not alphabetical on the symbol name(as reasonably sympy does) import sympy as sp sp.init_printing() U,tp, z, d = sp.symbols('U t_\perp z d') # do many operations with those symbols # the final expression is: z+tp**2+U+U/(z-3*tp)+d My problem is that SymPy presents the expression ordered as U + U/(-3*t_\perp + z) + d + t_
  • 使用 sympy 计算复杂根的因素(Factor to complex roots using sympy)
    问题 我无法弄清楚如何将多项式表达式分解为其复根。 >>> from sympy import * >>> s = symbol('s') >>> factor(s**2+1) 2 s + 1 回答1 您需要添加I作为代数扩展: In [2]: factor(x**2 + 1, extension=[I]) Out[2]: (x - ⅈ)⋅(x + ⅈ)
  • Force SymPy to keep the order of terms
    I have the following code: from sympy import * init_printing() x,y = symbols('x y') u = Function('u')(x,y) ux,uy,uxx,uxy,uyy = symbols("u_x u_y u_xx u_xy u_yy") mainEvaluation = uxx - 2*sin(x)*uxy - (cos(x) ** 2) * uyy - 2*ux + (2 - cos(x) + 2*sin(x) )*uy And when the output of print(mainExpression) is -2*u_x + u_xx - 2*u_xy*sin(x) + u_y*(2*sin(x) - cos(x) + 2) - u_yy*cos(x)**2 The problem is: I want the original order of variables. u_xx - 2*u_xy*sin(x) - u_yy*cos(x)**2 - 2*u_x + u_y*(2*sin(x) - cos(x) + 2) All this is done in IPython notebook. Is there any way to keep order?
  • 算法中的常数因子和低阶项是什么?(What is constant factors and low-order term in algorithms?)
    问题 在以下视频中,对渐近分析进行了解释:https://class.coursera.org/algo-004/lecture/169 但是我不明白什么是“低阶术语”和“常数因子”本身? (在视频的第4分钟)。 合并排序为6n*log2(n)+6n 。 为什么在这里6n是低阶项,而6是constant factor呢? 这些术语有具体定义吗? 回答1 低阶字词: 这里的“顺序”是指数量级。 当处理非常简单的术语(例如x或x 2时,该概念易于理解和解释。 x具有1的数量级,因为它可以写为x 1 ,而x 2具有2的数量级-数量级等于该项中变量的幂。 但是,当您通过例如添加log使事情复杂化时,事情变得更加朦胧(至少对我而言)。 [1] 在有些方面非正式, f(x)是一个低阶比g(x)如果f(x) < g(x)为x趋向于无穷大。 很容易看到f(n) = 6n比g(n) = 6n*log2(n)一些,只不过是用了一个非常大的值代替n (正确的方法是用数学证明,但用大的n代替价值往往只适用于简单的术语)。 术语本质上是用加/减符号分隔的事物。 因此,低阶术语只是比其他术语低阶的任何术语。 大概这与前导术语相反,前导术语是数量级最大的术语。 [1]:我经常处理big-O,但是已经有一段时间了(高中吗?),因为我已经处理了数量级的基础知识,所以如果我可能错过或忘记了有关该部分的内容
  • 如何在 ipython-notebook 中获取 sympy 表达式的乳胶表?(How to get a latex table of sympy expressions in ipython-notebook?)
    问题 我正在使用 sympy 从几个表达式中收集术语,并希望在表格中格式化结果(在 ipython-notebook 中),术语位于最左侧的列中,随后的每一列代表一个表达式。 该列中的条目来自sympy.collect(syms, evaluate=False)返回的dict 到目前为止,我有: from IPython.display import display, Latex import pandas as pd import sympy as sym sym.init_printing() x,y,z = sym.symbols('x,y,z') da,db,dc = sym.symbols('{\Delta}a {\Delta}b {\Delta}c ' ) e_list = [] d_list = [] e_list.append(da*2*x + da*(y - 2) + db*3*z + dc*(x+y)) e_list.append(dc*z + dc*x + da*x + db*(z+2)) for e in e_list: display(e.expand().collect((x,y,z))) d_list.append(e.expand().collect((x,y,z),evaluate=False)) df = pd.DataFrame(d_list)
  • 可用于矩阵形式的微分运算符,在 Python 模块 Sympy 中(Differential Operator usable in Matrix form, in Python module Sympy)
    问题 我们需要两个微分算子[B]和[C]矩阵,例如: B = sympy.Matrix([[ D(x), D(y) ], [ D(y), D(x) ]]) C = sympy.Matrix([[ D(x), D(y) ]]) ans = B * sympy.Matrix([[x*y**2], [x**2*y]]) print ans [x**2 + y**2] [ 4*x*y] ans2 = ans * C print ans2 [2*x, 2*y] [4*y, 4*x] 这也可以用于计算矢量场的卷曲,例如: culr = sympy.Matrix([[ D(x), D(y), D(z) ]]) field = sympy.Matrix([[ x**2*y, x*y*z, -x**2*y**2 ]]) 要使用 Sympy 解决这个问题,必须创建以下 Python 类: import sympy class D( sympy.Derivative ): def __init__( self, var ): super( D, self ).__init__() self.var = var def __mul__(self, other): return sympy.diff( other, self.var ) 当微分运算符的矩阵在左边相乘时,这个类单独解决。
  • SymPy:如何根据其他表达式返回一个表达式?(SymPy: How to return an expression in terms of other expression(s)?)
    问题 我对SymPy相当陌生,可能有一个基本问题。 否则我可能只是在误解应该如何使用SymPy。 有没有一种方法可以创建一个不由原子表示,而是由其他表达式组合而成的表达式? 例子: >>> from sympy.physics.units import * >>> expr1 = m/s >>> expr2 = mile/hour >>> expr1 m/s >>> expr2 1397*m/(3125*s) >>> expr1.in_terms_of([mile,hour]) #in my dreams? 3125*mile/(1397*hour) >>> 附带说明:我可以找到完整SymPy文档的“官方” PDF(或其他可打印)版本吗? (我在工作中受到严苛的Internet使用限制,厌倦了周末在家工作。) 更新: 这就是我遵循Prelude的建议而最终得到的结果,但是这样感觉不太好,因此不太可能得到太多使用。 评论和对WTF的欢迎。 def in_terms_of(self, terms): expr2 = eval(str(self), physics.units.__dict__) converter = {} for term in terms: term_expr = physics.units.__dict__[term] coeff = term_expr.as
  • Multivariate Taylor approximation in sympy
    I aim to write a multidimensional Taylor approximation using sympy, which uses as many builtin code as possible, computes the truncated Taylor approximation of a given function of two variables returns the result without the Big-O-remainder term, as e.g. in sin(x)=x - x**3/6 + O(x**4). Here is what I tryed so far: Approach 1 Naively, one could just combine the series command twice for each variable, which unfortunately does not work, as this example shows for the function sin(x*cos(y)): sp.sin(x*sp.cos(y)).series(x,x0=0,n=3).series(y,x0=0,n=3) >>> NotImplementedError: not sure of order of O(y*
  • 长表达式使 SymPy 崩溃(Long expression crashes SymPy)
    问题 我使用的是 64 位 Python 3.3.1、pylab 和 32GB 系统 RAM。 这个功能: def sqrt2Expansion(limit): x = Symbol('x') term = 1+1/x for _ in range(limit): term = term.subs({x: (2+1/x)}) return term.subs({x: 2}) 产生这种表达式: 1 + 1/(2 + 1/(2 + 1/(2 + 1/(2 + 1/(2 + 1/(...)))))) 。 当被调用时: sqrt2Expansion(100)返回有效结果,但sqrt2Expansion(200)产生RuntimeError和许多回溯页面,并挂起 pylab/IPython 解释器,大量系统内存未使用。 任何想法如何更有效地实施它? 我想调用sqrt2Expansion(1000)并且仍然得到结果。 回答1 我将尝试详细说明我在上面发布的评论。 Sympy 表达式是树。 每个操作都是一个节点,其操作数作为分支。 例如x+y看起来像Add(x, y)和x*(y+z)像Mul(x, Add(y, z)) 。 通常这些表达式会像Add(x, Add(y, z))那样自动变平Add(x, Add(y, z))变成Add(x, y, z) ,但对于更复杂的情况,可以得到非常深的树。
  • 如何使用Python求解一对非线性方程?(How to solve a pair of nonlinear equations using Python?)
    问题 使用Python解决一对非线性方程式的(最佳)方法是什么? (Numpy,Scipy或Sympy) 例如: x + y ^ 2 = 4 e ^ x + xy = 3 解决以上问题的代码段会很棒 回答1 对于数值解,可以使用fsolve: http://docs.scipy.org/doc/scipy/reference/generation/scipy.optimize.fsolve.html#scipy.optimize.fsolve from scipy.optimize import fsolve import math def equations(p): x, y = p return (x+y**2-4, math.exp(x) + x*y - 3) x, y = fsolve(equations, (1, 1)) print equations((x, y)) 回答2 如果您喜欢sympy,则可以使用nsolve。 >>> nsolve([x+y**2-4, exp(x)+x*y-3], [x, y], [1, 1]) [0.620344523485226] [1.83838393066159] 第一个参数是方程式列表,第二个参数是变量列表,第三个参数是初始猜测。 回答3 简短答案:使用fsolve 正如其他答案中提到的那样