Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用python求复杂函数的导数_Python_Math_Numpy - Fatal编程技术网

用python求复杂函数的导数

用python求复杂函数的导数,python,math,numpy,Python,Math,Numpy,我想推导一个相当复杂的扩散关系。 以下是色散关系的代码: import numpy as np import pylab as pl #function definitions. compare following paper eqs. (60) and (61) #"Hamiltionian formalism for two magnon scattering microwave relaxation: #Theory and applications" #Krivosik, Kalari

我想推导一个相当复杂的扩散关系。 以下是色散关系的代码:

import numpy as np
import pylab as pl

#function definitions. compare following paper eqs. (60) and (61)
#"Hamiltionian formalism for two magnon scattering microwave relaxation:
#Theory and applications"
#Krivosik, Kalarickal, Patton
#JAP 101, 083901 (2007)

def omega(gamma,Bx,By): #resonance frequency
    return gamma*sqrt(Bx*By)

def Bx(B,A,k,mu_0,Ms,Nk): #magnetic field in x-direction
    return B+(2*A/Ms)*k**2+mu_0*Ms*Nk

def By(B,A,k,mu_0,Ms,phi,Nk): #magnetic field in y-direction
    return B+(2*A/Ms)*k**2+mu_0*Ms*(sin(phi)**2)*(1-Nk)

def k(kx,n,w): #k-vektor of spin wave
    return sqrt(kx**2+(n*pi/w)**2)

def Nk(k,d): #Dipole field function
    return (1-exp(-k*d))/(k*d)

def phi(kx,n,w): #angle between k vector and magnetization which points along x-axis
    return arctan(n*pi/(w*kx))

#constants and parameters
gamma=28 #GHz/T
mu_0=4*pi*1e-7 #As/Vm

#range of k-vectors
kx=linspace(0,25000000,1000)

#sample parameters
A=3.5e-12 #J/m
Ms=140000 #A/m
B=0.05 #mT
w=2e-6 #m
d=100e-9 #m

fig=pl.figure(num=None, figsize=(10, 6.25), dpi=80, facecolor='w', edgecolor='k')
font = {'weight' : 'normal', 'size'   : 13}
matplotlib.rc('font', **font)

n=1
plot(kx/1e6, omega(gamma,Bx(B,A,k(kx,n,w),mu_0,Ms,Nk(k(kx,n,w),d)),By(B,A,k(kx,n,w),mu_0,Ms,phi(kx,n,w),Nk(k(kx,n,w),d))), 'k-')
现在我想推导这个函数,因为函数的斜率对我来说至关重要

  • 有没有更简单的方法来定义函数

  • 对于导数,我需要计算d_ω/d_kx。我不需要解析表达式!你推荐哪条路

  • 我应该只取ω的值并手动计算吗

    (ω(n+1)-ω(n))/(kx(n+1)-kx(n))

    还是有更优雅的方式


  • 您可以使用函数梯度,它是在numpy中实现的

    使用内部的中心差和边界处的第一个差计算渐变。因此,返回的梯度与输入数组具有相同的形状

    这就是如何使用它来绘制导数,只需复制您的示例

    plot(kx/1e6, gradient(omega(gamma,Bx(B,A,k(kx,n,w),mu_0,Ms,Nk(k(kx,n,w),d)),By(B,A,k(kx,n,w),mu_0,Ms,phi(kx,n,w),Nk(k(kx,n,w),d)))), 'k-')
    
    希望有帮助。

    您可以依赖scipy实用程序函数,该函数允许同时使用离散化
    dx
    的大小和有限差分格式的顺序(默认设置为
    3
    )。这是一个例子:

    from scipy.misc import derivative
    f=lambda kx : omega(gamma,Bx(B,A,k(kx,n,w),mu_0,Ms,Nk(k(kx,n,w),d)),By(B,A,k(kx,n,w),mu_0,Ms,phi(kx,n,w),Nk(k(kx,n,w),d)))
    df = derivative(f,kx,dx=kx[1]-kx[0])
    fig,ax=plt.subplots()
    ax.plot(kx/1e6,f(kx),'b')
    bx=ax.twinx()
    bx.plot(kx/1e6,df,'r')
    bx.grid()
    

    我找到了解决问题的办法

    #Definitions from above
    dispersion =lambda n : omega(gamma,Bx(B,A,k(kx,n,w),mu_0,Ms,Nk(k(kx,n,w),d)),By(B,A,k(kx,n,w),mu_0,Ms,phi(kx,n,w),Nk(k(kx,n,w),d)))
    derivative=diff(dispersion(n))/diff(kx)
    

    有多种方法:

  • 数值近似(如上所列)。
    • ,(刚刚更新到版本0.5)这使用有限差分方法,但跟踪数值误差估计,从而给出可靠的结果,即自动考虑网格大小
    • ,(刚刚更新到0.5版)
    • ,非常优雅的代码,感谢Theano和decorators
    • 有一个python包装器
  • 符号导数。
    • ,经典的python符号派生模块
    • ,一个类似iPython的环境,用于替代Mathematica,它构建在python上

  • 2和3都比数值导数更精确,因为为了保持精度,需要在非常精细的网格上对方程进行采样。

    如果使用numpy 1.9(当前的开发版本)梯度函数在边界上也使用二阶精度差分,因此在整个导数上保持精度:)这是一个很好的改进!;)这个函数似乎没有提供正确的值。可能是因为梯度函数不知道我的kx值。gradient()强烈地依赖于点的数量。这是正确的,但您也可以将差异作为参数包含到gradient函数中。梯度(func[1:],diff(func))。在这种情况下,结果与您在下面的帖子中实现的结果类似,但边缘的值可能是错误的。如果您使用具有多个维度的数组,这将非常方便。这似乎不起作用。函数对kx=0的导数为0,noch为3.1?来自的渐变工具提供了正确的结果。您可能不需要导数的符号表达式,但数值微分容易出错,因此我的建议是构造一个符号表达式(例如,通过Sympy)并对其进行计算。numdifftools是数值近似,而不是自动微分。