天道酬勤,学无止境

如何在 Sympy 中进行函数组合?(How to do function composition in Sympy?)

问题

我想做类似h = f(g(x))事情,并能够区分h,例如h.diff(x) 。 对于像h = cos(x)这样的一个函数,这实际上是可能的,并且文档清楚地说明了这一点。

但是对于函数组合,就不是那么清楚了。 如果你已经这样做了,请给我看一个例子或将我链接到相关文档。

(如果 Sympy 无法做到这一点,您是否知道其他任何可以做到这一点的软件包,即使它是非 Python 的)

谢谢你。

回答1

在 sympy 中,函数组合似乎像您期望的那样工作:

import sympy
h = sympy.cos('x')
g = sympy.sin(h)
g
Out[245]: sin(cos(x))

或者如果你喜欢

from sympy.abc import x,y
g = sympy.sin('y')
f = g.subs({'y':h})

然后你可以调用 diff 来获取你的导数。

g.diff()
Out[246]: -sin(x)*cos(cos(x))

受限制的 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在ipython笔记本中进行漂亮的打印?(How to pretty print in ipython notebook via sympy?)
    问题 我尝试了pprint , print ,前者只能打印Unicode版本,而后者却不能打印出漂亮的照片。 from sympy import symbols, Function import sympy.functions as sym from sympy import init_printing init_printing(use_latex=True) from sympy import pprint from sympy import Symbol x = Symbol('x') # If a cell contains only the following, it will render perfectly. (pi + x)**2 # However I would like to control what to print in a function, # so that multiple expressions can be printed from a single notebook cell. pprint((pi + x)**2) 回答1 您需要使用显示: from IPython.display import display display(yourobject) 它将选择适当的表示形式(text / LaTex / png ...),在默认情况下
  • 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
  • 朱莉娅:如何将符号表达式转换为函数?(Julia: how do I convert a symbolic expression to a function?)
    问题 我已经使用SymPy包(https://github.com/jverzani/SymPy.jl)创建了一个符号表达式。 我现在想使用Roots包(https://github.com/JuliaLang/Roots.jl)查找该表达式的根。 但是,我无法弄清楚如何使用fzeros方法查找根,因为该方法只能应用于Function类型而不是Sym (即我的表达式的类型)的对象。 这是我要做的事的一个例子。 我创建一个符号"x"和一个符号表达式sin(x) 。 现在让我们尝试在值-10和10之间找到sin(x)的零: using SymPy x = sym"x" expr = sin(x) using Roots fzeros(expr,-10,10) 这是错误: ERROR: `fzeros` has no method matching fzeros(::Sym, ::Int64, ::Int64) 如何将Sym类型的表达式转换为Function类型,以便找到根? 回答1 [更新:在许多情况下,以下讨论已被最近引入的lambdify函数所取代。 调用lambdify(expr)创建一个julia函数,该函数不会回调SymPy进行评估,因此应该更快。 它应该适用于大多数(当然不是全部)表达式。] 这是一个两步过程: convert(Function, expr) 在您的情况下
  • 强制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
  • 快速评估大量输入值的数学表达式(函数)(Evaluating a mathematical expression (function) for a large number of input values fast)
    问题 以下问题 评估字符串中的数学表达式 Python中的方程式解析在Python中解析用户提供的数学公式的安全方法从Python中不安全的用户输入评估数学方程式 和它们各自的答案使我想到如何有效地解析(或多或少受信任的)用户给出的单个数学表达式(按照该答案的大致术语https://stackoverflow.com/a/594294/1672565)来自数据库的20k到30k的输入值。 我实施了一个快速而肮脏的基准测试,因此可以比较不同的解决方案。 # Runs with Python 3(.4) import pprint import time # This is what I have userinput_function = '5*(1-(x*0.1))' # String - numbers should be handled as floats demo_len = 20000 # Parameter for benchmark (20k to 30k in real life) print_results = False # Some database, represented by an array of dicts (simplified for this example) database_xy = [] for a in range(1, demo_len
  • Python:如何评估一个字符串函数?(Python: How to evaluate a function which is string?)
    问题 我从数据库中得到一些模型 f(t)=(2.128795454425367)+(208.54359721863273)*t+(26.098128487929266)*t^2+(3.34369909584111)*t^3+(-0.3450228278737971)*t^4+(-0.018630757967458885)*t^5+(0.0015029038553239819)*t^6; 其中一些作为字符串。 我需要为t in range(1, 13)评估此函数 现在我必须手动复制这些功能并运行它们 print [1.2381648958643592 + \ 153.55656654019816 * t +\ 22.99318731025164 * (t**2) +\ 11.060577906796075 * (t**3) +\ -1.3465054084767891 * (t**4) + \ 0.016926765998876842 * (t**5) +\ 0.001500086893490721 * (t**6) for t in range(1, 13)] 有没有更好的办法在python中做到这一点? 回答1 如果性能不是主要问题-如果您仅以12分来评估它,我怀疑不是-那么您可以利用方便的sympy库为您做很多工作。 例如: >>> import sympy >>> sympy
  • How to do function composition in Sympy?
    I want to do something like h = f(g(x)) and be able to differentiate h, like h.diff(x). For just one function like h = cos(x) this is in fact possible and the documentation makes it clear. But for function compositions it is not so clear. If you have done this, kindly show me an example or link me to the relevant document. (If Sympy can't do this, do you know of any other packages that does this, even if it is non-python) thank you.
  • 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
  • 如何在SymPy中加速慢矩阵乘法?(How to accelerate slow matrix multiplication in SymPy?)
    问题 我当时正在编写一种工具来用SymPy解决特定的递归方程,结果发现涉及矩阵乘法的步骤之一花费的时间特别长。 例如,如果我在iPython控制台中尝试以下操作, In [1]: from sympy import * In [2]: A = Matrix(500, 500, lambda i,j: 2 + abs(i-j) if i-j in [-1, 0, 1] else 0) In [3]: A[0:7, 0:7] Out[3]: Matrix([ [2, 3, 0, 0, 0, 0, 0], [3, 2, 3, 0, 0, 0, 0], [0, 3, 2, 3, 0, 0, 0], [0, 0, 3, 2, 3, 0, 0], [0, 0, 0, 3, 2, 3, 0], [0, 0, 0, 0, 3, 2, 3], [0, 0, 0, 0, 0, 3, 2]]) In [4]: A * A ... 我从来没有等待足够长的时间来完成它。 我欣赏符号处理比数值计算要慢得多,但这似乎很荒谬。 使用八度或其他线性代数包可以在几分之一秒内执行此计算。 有谁有经验将SymPy的矩阵类用于带有Rational条目的约1000行和列? 回答1 任意精度都是必须的,速度是一个不错的选择 有一些用于此类目的的pythonic类,您可能会对您的任意精度计算感兴趣 decimal.Decimal
  • 如何在MATLAB中使用符号表达式创建函数?(How do I make a function from a symbolic expression in MATLAB?)
    问题 如何通过符号表达式创建函数? 例如,我有以下内容: syms beta n1,n2,m,aa= Constants u = sqrt(n2-beta^2); w = sqrt(beta^2-n1); a = tan(u)/w+tanh(w)/u; b = tanh(u)/w; f = (a+b)*cos(aa*u+m*pi)+a-b*sin(aa*u+m*pi); %# The main expression 如果要在特殊程序中使用f来查找其零,如何将f转换为函数? 或者,我应该怎么做才能找到f和此类嵌套表达式的零? 回答1 您有几种选择... 选项1:自动生成函数 如果您使用的是4.9版(R2007b +)或更高版本的Symbolic Toolbox,则可以使用matlabFunction函数将符号表达式转换为匿名函数或函数M文件。 文档中的示例: >> syms x y >> r = sqrt(x^2 + y^2); >> ht = matlabFunction(sin(r)/r) ht = @(x,y)sin(sqrt(x.^2+y.^2)).*1./sqrt(x.^2+y.^2) 选项2:手动生成函数 由于您已经编写了一组符号方程式,因此您只需将部分代码剪切并粘贴到函数中即可。 这是您上面的示例所示: function output = f(beta,n1,n2,m
  • 如何使用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 正如其他答案中提到的那样
  • Python中的简单素数生成器(Simple prime number generator in Python)
    问题 有人可以告诉我这段代码在做什么吗? 无论如何,它只是打印“计数”。 我只想要一个非常简单的素数生成器(没什么花哨的)。 import math def main(): count = 3 one = 1 while one == 1: for x in range(2, int(math.sqrt(count) + 1)): if count % x == 0: continue if count % x != 0: print count count += 1 回答1 有一些问题: 当计数不除以x时,为什么要打印计数? 这并不意味着它是素数,仅意味着这个特定的x不会将其除 continue移动到下一个循环迭代-但您确实想使用break停止它 这是您的代码,其中包含一些修复程序,它仅输出质数: import math def main(): count = 3 while True: isprime = True for x in range(2, int(math.sqrt(count) + 1)): if count % x == 0: isprime = False break if isprime: print count count += 1 有关更有效的质子生成,请参见其他人所建议的Eratosthenes筛。 这是一个不错的,经过优化的实现,其中包含许多注释:
  • 如何在sympy中创建索引变量?(How to create an indexed variable in sympy?)
    问题 x,i,n = symbols("x i n") summation(x,(i,1,n)) 如何使x被i索引? 回答1 没有数字上限,它什么也不会做,但是您可以使用类似函数的表达式或索引变量: >>> Sum(Indexed('x',i),(i,1,3)) Sum(x[i], (i, 1, 3)) >>> _.doit() x[1] + x[2] + x[3] >>> x = Function('x') >>> Sum(x(i),(i,1,3)).doit() x(1) + x(2) + x(3) >>> Sum(x(i),(i,1,n)).doit() Sum(x(i), (i, 1, n))
  • 从值数组评估sympy表达式(Evaluate sympy expression from an array of values)
    问题 我正在试验sympy,遇到了一个我无法解决的问题。 使用scipy,我可以编写一个表达式,并为x值数组求值,如下所示: import scipy xvals = scipy.arange(-100,100,0.1) f = lambda x: x**2 f(xvals) 使用sympy,我可以编写相同的表达式,如下所示: import sympy x = sympy.symbols('x') g = x**2 通过执行以下操作,我可以为单个值求值该表达式: g.evalf(subs={x:10}) 但是,我无法像我使用scipy一样,想出如何对x值数组进行求值的方法。 我该怎么做? 回答1 首先,目前SymPy不保证支持numpy数组,在这种情况下,这就是您想要的。 检查此错误报告http://code.google.com/p/sympy/issues/detail?id=537 其次,如果您想对许多值进行数值评估,SymPy并不是最佳选择(毕竟它是一个符号库)。 使用numpy和scipy。 但是,要进行数字评估的一个合理原因是,要推导要评估的表达式很困难,因此您可以在SymPy中将其派生,然后在NumPy / SciPy / C / Fortran中对其进行评估。 要将表达式转换为numpy,只需使用 from sympy.utilities.lambdify
  • 如何获得sympy表达式中的符号列表?(How can I get a list of the symbols in a sympy expression?)
    问题 例如,如果我跑步 import sympy x, y, z = sympy.symbols('x:z') f = sympy.exp(x + y) - sympy.sqrt(z) 我可以使用f任何方法来获取表达式包含的sympy.Symbol对象的列表或元组吗? 我宁愿不必解析srepr(f)或通过f.args向下解析。 在这种情况下, g.args[0].args[1].args[0]给我Symbol("z") ,而g.args[1].args[0].args给我元组(Symbol("x"), Symbol("y")) ,但显然这些是特定于表达式的。 回答1 您可以使用: f.free_symbols 这将返回一组所有免费符号。 例子: >>> import sympy >>> x, y, z = sympy.symbols('x:z') >>> f = sympy.exp(x + y) - sympy.sqrt(z) >>> f.free_symbols set([x, z, y]) 回答2 请注意,JuniorCompressors答案仅列出自由变量。 如果您有“总和”,“产品”,“积分”或类似的东西,则可能会或可能不想使用.variables属性来另外了解积分/求和变量: In [216]: (x, n) = sympy.symbols("x n") In [217]
  • 使用SciPy集成返回矩阵或数组的函数(using SciPy to integrate a function that returns a matrix or array)
    问题 我有一个符号数组,可以表示为: from sympy import lambdify, Matrix g_sympy = Matrix([[ x, 2*x, 3*x, 4*x, 5*x, 6*x, 7*x, 8*x, 9*x, 10*x], [x**2, x**3, x**4, x**5, x**6, x**7, x**8, x**9, x**10, x**11]]) g = lambdify( (x), g_sympy ) 这样对于每个x我得到一个不同的矩阵: g(1.) # matrix([[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.], # [ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]) g(2.) # matrix([[ 2.00e+00, 4.00e+00, 6.00e+00, 8.00e+00, 1.00e+01, 1.20e+01, 1.40e+01, 1.60e+01, 1.80e+01, 2.00e+01], # [ 4.00e+00, 8.00e+00, 1.60e+01, 3.20e+01, 6.40e+01, 1.28e+02, 2.56e+02, 5.12e+02, 1.02e+03, 2.05e+03]]) 等等... 我需要数值积分g过x ,说from 0. to
  • SymPy / SciPy:求解具有不同变量的常微分方程组(SymPy/SciPy: solving a system of ordinary differential equations with different variables)
    问题 我是SymPy和Python的新手,目前正在使用Python 2.7和SymPy 0.7.5,目的是:a)从文本文件中读取微分方程组b)求解系统 我已经阅读了这个问题和另一个问题,它们几乎是我要寻找的,但是我还有一个问题:我事先不知道方程式的形式,所以我无法使用def创建相应的函数def在脚本中,如本例所示。 整个事情必须在运行时进行管理。 因此,这是我的代码片段。 假设我有一个包含以下内容的文本文件system.txt : dx/dt = 0.0387*x - 0.0005*x*y dy/dt = 0.0036*x*y - 0.1898*y 我要做的是: # imports import sympy import scipy import re as regex # define all symbols I am going to use x = sympy.Symbol('x') y = sympy.Symbol('y') t = sympy.Symbol('t') # read the file systemOfEquations = [] with open("system.txt", "r") as fp : for line in fp : pattern = regex.compile(r'.+?\s+=\s+(.+?)$') expressionString
  • 如何从矩阵中找到线性独立的行(How to find linearly independent rows from a matrix)
    问题 如何从矩阵中识别线性​​独立的行? 例如, 第四行是独立的。 回答1 首先,您的第三行与第一行和第二行线性相关。 但是,您的第一列和第四列是线性相关的。 您可以使用两种方法: 特征值 如果矩阵的一个特征值是零,则其对应的特征向量是线性相关的。 文档eig指出,返回的特征值将根据其多重性进行重复,并且不一定是有序的。 但是,假设特征值与您的行向量相对应,则一种方法是: import numpy as np matrix = np.array( [ [0, 1 ,0 ,0], [0, 0, 1, 0], [0, 1, 1, 0], [1, 0, 0, 1] ]) lambdas, V = np.linalg.eig(matrix.T) # The linearly dependent row vectors print matrix[lambdas == 0,:] Cauchy-Schwarz不等式 要测试向量的线性相关性并找出哪个向量,可以使用Cauchy-Schwarz不等式。 基本上,如果向量的内积等于向量范数的乘积,则向量是线性相关的。 这是列的示例: import numpy as np matrix = np.array( [ [0, 1 ,0 ,0], [0, 0, 1, 0], [0, 1, 1, 0], [1, 0, 0, 1] ]) print np
  • Sympy-比较表达式(Sympy - Comparing expressions)
    问题 有没有办法检查两个表达式在数学上是否相等? 我期望tg(x)cos(x) == sin(x)输出True ,但输出False 。 有没有办法与sympy进行这种比较? 另一个例子是(a+b)**2 == a**2 + 2*a*b + b**2令人惊讶地还输出False 。 我发现了一些类似的问题,但没有一个涵盖这个确切的问题。 回答1 从SymPy文档 ==表示精确的结构相等性测试。 这里的“精确”表示两个表达式仅在结构上完全相等时才将它们与==进行比较。 在此,(x + 1)^ 2和x ^ 2 + 2x + 1在符号上不同。 一是两个项相加的乘方,另一个是三项相加的乘方。 事实证明,将SymPy用作库时,使用==测试精确的符号相等性比使用它表示符号相等性或测试数学相等性要有用得多。 但是,作为新用户,您可能会更关心后两者。 我们已经看到了用符号表示等式的另一种方法。 为了测试两个事物是否相等,最好回顾一下一个基本事实:如果a = b,则ab = 0。 因此,检查a = b是否为最佳方法是采用ab并将其简化,然后查看其是否变为0。我们将在后面了解到,执行此操作的函数称为简化。 该方法并非绝对可靠-实际上,从理论上可以证明,不可能确定两个符号表达式在总体上是否相等,但是对于大多数常见表达式而言,它工作得很好。 作为针对您特定问题的演示,我们可以使用等价表达式的减法并与0进行比较
  • 如何创建Python Lambda列表(在列表理解/ for循环中)?(How do I create a list of Python lambdas (in a list comprehension/for loop)?)
    问题 我想从Python中的常量列表创建lambda对象列表; 例如: listOfNumbers = [1,2,3,4,5] square = lambda x: x * x listOfLambdas = [lambda: square(i) for i in listOfNumbers] 但是,当我运行它们时,这将创建一个lambda对象的列表: for f in listOfLambdas: print f(), 我希望它会打印 1 4 9 16 25 而是打印: 25 25 25 25 25 似乎所有lambda都被赋予了错误的参数。 我做错了什么,有办法解决吗? 我认为我使用的是Python 2.4。 编辑:更多尝试的事情,这样想出了这个: listOfLambdas = [] for num in listOfNumbers: action = lambda: square(num) listOfLambdas.append(action) print action() 打印从1到25的期望平方,但是使用先前的print语句: for f in listOfLambdas: print f(), 仍然给了我全部25秒的时间。 现有的lambda对象如何在这两个打印调用之间改变? 相关问题:为什么map()和列表理解的结果不同? 回答1