繁体   English   中英

用python导出复杂函数

[英]Derivative of complicated function with python

我有一个非常复杂的diepersion关系,我想得出。 以下是色散关系的代码:

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-')

现在我想推导出这个函数,因为函数的斜率对我来说至关重要......

  1. 是否有更简单的方法来定义函数?

  2. 对于导数,我需要计算d_omega / d_kx。 我不需要解析表达! 你会推荐哪种方式?

  3. 我应该只采取欧米茄的值并手动计算

    (欧米加(N + 1)-omega(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-')

希望能帮助到你。

有很多方法:

  1. 数值逼近(如上所述)。
    • numdifftools ,(刚刚更新到版本0.5),它使用有限差分方法,但跟踪数值误差估计,从而给出可靠的结果,即它自动处理网格尺寸。
  2. 自动区分
  3. 符号衍生物。
    • sympy ,经典的蟒蛇象征性衍生模块
    • Sage ,一种类似iPython的环境,旨在替代Mathematica,基于python构建。

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

你可以依赖这个 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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM