简体   繁体   English

用python导出复杂函数

[英]Derivative of complicated function with python

I have a pretty complicated diespersion relation which I want to derive. 我有一个非常复杂的diepersion关系,我想得出。 Here is the code for the dispersion relation: 以下是色散关系的代码:

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

Now I want to derive the function since the slope of the function is of crucial importance for me... 现在我想推导出这个函数,因为函数的斜率对我来说至关重要......

  1. Is there an easier way to define the function? 是否有更简单的方法来定义函数?

  2. For the derivative I need to calculate d_omega/d_kx. 对于导数,我需要计算d_omega / d_kx。 I do not need the analytical expression! 我不需要解析表达! Which way would you recommend? 你会推荐哪种方式?

  3. Should I just take the values of omega and compute manually 我应该只采取欧米茄的值并手动计算

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

    or is there a more elegant way? 还是有更优雅的方式?

You can use the function gradient, which is implemented in numpy. 您可以使用函数渐变,它在numpy中实现。

The gradient is computed using central differences in the interior and first differences at the boundaries. 使用内部的中心差异和边界处的第一个差异来计算梯度。 The returned gradient hence hasthe same shape as the input array. 返回的渐变因此具有与输入数组相同的形状。

This is how you can use it to plot the derivative, just copying your example. 这就是你如何使用它绘制衍生物,只是复制你的例子。

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

Hope it helps. 希望能帮助到你。

There are a number of ways: 有很多方法:

  1. Numerical approximation (as listed above by others). 数值逼近(如上所述)。
    • numdifftools , (just updated to version 0.5) this uses a finite difference approach but keeps track of the numerical error estimate thus giving reliable results ie it automatically takes care of mesh size. numdifftools ,(刚刚更新到版本0.5),它使用有限差分方法,但跟踪数值误差估计,从而给出可靠的结果,即它自动处理网格尺寸。
  2. Automatic differentiation . 自动区分
  3. Symbolic derivative. 符号衍生物。
    • sympy , the classic python symbolic derivative module sympy ,经典的蟒蛇象征性衍生模块
    • Sage , an iPython-like environment intended as a alternative to Mathematica, built on python. Sage ,一种类似iPython的环境,旨在替代Mathematica,基于python构建。

Both 2 and 3 will be more accurate than numerical derivatives because to preserve accuracy you need to sample the equation over a very fine mesh. 2和3都比数值导数更准确,因为为了保持准确性,您需要在非常精细的网格上对方程进行采样。

You can rely on this scipy utility function, that allows to play both with the size of the discretization dx and with order of the finite difference scheme, set by default to 3 . 你可以依赖这个 scipy效用函数,它允许同时使用离散化dx的大小和有限差分格式的顺序,默认设置为3 This is an example: 这是一个例子:

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

在此输入图像描述

I found a solution for my problem 我找到了解决问题的方法

#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