用python导出复杂函数

时间:2014-03-05 12:33:33

标签: python math numpy

我有一个非常复杂的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. 我应该只取omega的值并手动计算

    (欧米加(N + 1)-omega(N))/(KX(N + 1)-kx(n))的

    还是有更优雅的方式?

4 个答案:

答案 0 :(得分:1)

您可以使用函数渐变,这是在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 :(得分:1)

有很多方法:

  1. 数值近似(由其他人列出)。
    • numdifftools,(刚刚更新到版本0.5),它使用有限差分方法,但跟踪数值误差估计,从而提供可靠的结果,即它自动处理网格尺寸。
  2. Automatic differentiation
  3. 符号衍生物。
    • sympy,经典的python符号衍生模块
    • Sage,一个类似iPython的环境,旨在替代Mathematica,构建于python之上。
  4. 2和3都比数值导数更精确,因为为了保持准确性,您需要在非常精细的网格上对方程进行采样。

答案 2 :(得分:0)

您可以依赖this 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()

enter image description here

答案 3 :(得分:0)

我找到了解决问题的方法

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