通过SymPy区分多变量函数并在某一点进行评估

时间:2018-01-20 12:18:13

标签: python python-3.x syntax-error sympy differentiation

我想使用SymPy得到多变量函数的导数,然后a)要打印的符号结果,然后b)要打印的点的导数结果。我使用以下代码

 import math as m
 import numpy
 import scipy

 #define constants                                                               
 lambdasq = 0.09
 Ca = 3
 qOsq = 2

 def  f1(a,b,NN,ktsq,x):
      return NN*x**(-a)*ktsq**b*m.exp(m.sqrt(16*Ca/9*m.log(1/x)*m.log((m.log(ktsq/lambdasq))/m.log(qOsq/lambdasq))))

from sympy import *
x = symbols('x')

def f2(NN,a,b,x,ktsq):
    return  -x*diff(m.log(f1),x)

这样运行,但我无法找到一种方法来打印符号结果,当我尝试评估某个点时,例如添加print(f2(0.3,0.1,-0.2,0.1,3))我收到错误

  TypeError: must be real number, not function

当我用其符号表示替换f1时,我得到了错误

  ValueError: 
  Can't calculate 1st derivative wrt 0.100000000000000.

所以我可以总结一下我的问题如下

a)如何在我调用diff(m.log(f1),x)时打印出符号导数及其值(即无需用实际表示替换f1

b)如果我必须在区分中使用符号表示(即使用diff(m.log(NN*x**(-a)*ktsq**b*m.exp(m.sqrt(16*Ca/9*m.log(1/x)*m.log((m.log(ktsq\ /lambdasq))/m.log(qOsq/lambdasq))))),x)那么如何在某一点打印出符号导数及其值?

Python的新手,所以希望有一个相对简单的修复。 谢谢!

2 个答案:

答案 0 :(得分:1)

我正在发布此答案,因为在搜索“简单多变量差异”时,该线程在我的搜索引擎上排名第一。

示例1

import sympy as sp

def f(u):
    return (u[0]**2 + u[1]**10 + u[2] - 4)**2

u = sp.IndexedBase('u')

print(sp.diff(f(u), u[0]))

输出

4*(u[0]**2 + u[1]**10 + u[2] - 4)*u[0]

这是f(u)wrt u [0]的导数


示例2

如果我们想要整个雅各布人,我们可以这样做:

for i in range(3):
    print(sp.diff(f(u), u[i]))

输出

4*(u[0]**2 + u[1]**10 + u[2] - 4)*u[0]
20*(u[0]**2 + u[1]**10 + u[2] - 4)*u[1]**9
2*u[0]**2 + 2*u[1]**10 + 2*u[2] - 8

我们可以定义一个临时函数并复制粘贴这些行

def temp(u):
    return np.array([
        4*(u[0]**2 + u[1]**10 + u[2] - 4)*u[0],
        20*(u[0]**2 + u[1]**10 + u[2] - 4)*u[1]**9,
        2*u[0]**2 + 2*u[1]**10 + 2*u[2] - 8,
    ])

temp([1., 1., 1.])

这将输出array([ -4., -20., -2.])

并进行验证

from autograd import grad
gradient = grad(f)
gradient([1., 1., 1.])

此输出:[array(-4.), array(-20.), array(-2.)]

注意:这只是一个简单的展示,您可以了解如何在sympy中进行多元派生。希望我可以帮助某人

答案 1 :(得分:0)

首先,math函数是数字的,它们不能与SymPy的符号一起使用。使用已使用from sympy import *导入的SymPy(exp,log,sqrt)中的相应函数:

def f1(a, b, NN, ktsq, x):
    return NN*x**(-a)*ktsq**b*exp(sqrt(16*Ca/9*log(1/x)*log((log(ktsq/lambdasq))/log(qOsq/lambdasq))))

其次,在f2中你试图区分f1。但是f1是一个可调用的Python函数,而不是一个SymPy表达式。您需要传入一些参数来获取SymPy表达式,然后可以对其进行区分。

def f2(NN, a, b, x0, ktsq):
    return (-x*diff(log(f1(a, b, NN, ktsq, x)), x)).subs(x, x0)

这里除了值x0之外的数值参数被传递给f1,从而产生一个包含x的SymPy表达式。这是一个需要区分的事情。之后,数值x0代替x。

打印(f2(0.3,0.1,-0.2,0.1,3))#0.366748952743614

一个外卖点是SymPy区分表达式,而不是函数。 SymPy中没有f'的概念,只有f'(x)