我写了一个脚本来测试一些差异化方法。我使用正弦波作为测试数据。
这是脚本:
import sys, getopt
import matplotlib.pyplot as plt
import numpy as np
from scipy import integrate
from scipy import stats
def d1(x,y):
dydx=[0]
dydx.extend(np.diff(y)/np.diff(x))
xt=zip(x,x[1:],x[2:])
yt=zip(dydx,dydx[1:],dydx[2:])
n=0
dydx=[]
for i,j in zip(xt,yt):
X1=(i[0]+i[1])/2
X2=(i[1]+i[2])/2
m=(j[2]-j[1])/(X2-X1)
C=j[1]-m*(i[1]+i[0])/2
if n==0:
dydx.append(m*i[0]+C)
dydx.append(m*i[1]+C)
if n==len(xt)-1:
dydx.append(m*i[2]+C)
n+=1
return dydx
def d2(x,y):
x0=x[:-2]
x1=x[1:-1]
x2=x[2:]
y0=y[:-2]
y1=y[1:-1]
y2=y[2:]
f=(x2-x1)/(x2-x0)
return (1-f)*(y2-y1)/(x2-x1)+f*(y1-y0)/(x1-x0)
def d3(x,y):
z1 = np.hstack((y[0],y[:-1]))
z2 = np.hstack((y[1:],y[-1]))
dx1 = np.hstack((0,np.diff(x)))
dx2 = np.hstack((np.diff(x),0))
d=(z2-z1)/(dx2+dx1)
return d
def d4(x,y):
dx=np.gradient(x)
dy=np.gradient(y)
return dy/dx
def main(argv):
ifile="/dev/stdin"
ofile="/dev/stdout"
plot=False
graph=False
snr=False
ydata=False
n=1
dmethod=2
try:
opts, args=getopt.getopt(argv,"hi:o:ps:qf:yn:d:r",["ifile=","ofile="])
except getopt.GetoptError:
print(sys.argv[0] + ' [-i <inputfile>] [-o <outputfile>] [-d <int> ] [-n <int>] [-p] [-s <imagefile>] [-q] [-f <int>] [-y] [-r]')
sys,exit(1)
for opt, arg in opts:
if opt=='-h':
print(sys.argv[0] + ' [-i <inputfile>] [-o <outputfile>] [-d <int> ] [-n <int>] [-p] [-s <imagefile>] [-q] [-y]')
print('\t-n order of derivative (default=1)')
print('\t-d 1. modified central difference, 2. central difference (default=2)')
print('\t-p display plot')
print('\t-s save plot as imagefile (eps, jpeg, jpg, pdf, pgf, png, ps, raw, rgba, svg, svgz, tif, tiff)')
print('\t-i inputfile (default=/dev/stdin)')
print('\t-o outputfile (default=/dev/stdout)')
print('\t-q quiet; suppress output')
print('\t-r include signal-to-noise ratio in plot')
print('\t-y include y-data in output')
sys.exit()
elif opt in ("-i", "--ifile"):
ifile=arg
elif opt in ("-o", "--ofile"):
ofile=arg
elif opt in ("-q"):
ofile="/dev/null"
elif opt in ("-d"):
dmethod=int(arg)
elif opt in ("-w"):
w=int(arg)
elif opt in ("-p"):
plot=True
elif opt in ("-r"):
snr=True
elif opt in ("-s"):
graph=True
imagefile=arg
elif opt in ("-y"):
ydata=True
data=np.loadtxt(ifile)
x=data[:,0]
y=data[:,1]
yprime=y
if dmethod==1:
yprime=d1(data[:,0],data[:,1])
elif dmethod==2:
yprime=d3(data[:,0],data[:,1])
# Signal-to-noise calculations
stonrlist=[]
stonrlist.append(stats.signaltonoise(y))
stonrlist.append(stats.signaltonoise(yprime))
# Collect the data and write it
if ydata:
outdata=np.array([data[:,0],data[:,1],yprime])
fmt=['%4.1f','%12.5e','%12.5e']
else:
outdata=np.array([data[:,0],yprime])
fmt=['%4.1f','%12.5e']
outdata=outdata.T
np.savetxt(ofile,outdata,fmt)
# Build the plot
fig=plt.figure()
fig.set_size_inches(16,9)
if snr:
plt.plot(data[:,0],data[:,1],'-',color='black',label=ifile+'\n'+str(stonrlist[0]))
plt.plot(data[:,0],yprime,'-',color='red',label=ofile+'\n'+str(stonrlist[1]))
else:
plt.plot(data[:,0],data[:,1],'-',color='black',label=ifile)
plt.plot(data[:,0],yprime,'-',color='red',label=ofile)
plt.legend()
plt.minorticks_on()
plt.grid(which='major',linestyle='-',linewidth='0.3')
plt.grid(which='minor',linestyle=':',linewidth='0.3')
if plot:
plt.show()
if graph:
fig.savefig(imagefile,dpi=120)
main(sys.argv[1:])
结果如下:
注意幅度有多小。
为了测试微分器,我写了一个积分器。如果它们有任何好处,我应该恢复原来的功能(在这种情况下,是正弦波)。这是代码:
import sys, getopt
import matplotlib.pyplot as plt
import numpy as np
from scipy import integrate
def main(argv):
ifile="/dev/stdin"
ofile="/dev/stdout"
plot=False
graph=False
ydata=False
try:
opts, args=getopt.getopt(argv,"hi:o:ps:qf:y",["ifile=","ofile="])
except getopt.GetoptError:
print(sys.argv[0] + ' [-i <inputfile>] [-o <outputfile>] [-p] [-s <imagefile>] [-q] [-f <int>] [-y]')
sys,exit(1)
for opt, arg in opts:
if opt=='-h':
print(sys.argv[0] + ' [-i <inputfile>] [-o <outputfile>] [-f <float>] [-p] [-s <imagefile>] [-q] [-y]')
print('\t-p display plot')
print('\t-f first (initial) value (default=0.0)')
print('\t-s save plot as imagefile (eps, jpeg, jpg, pdf, pgf, png, ps, raw, rgba, svg, svgz, tif, tiff)')
print('\t-i inputfile (default=/dev/stdin)')
print('\t-o outputfile (default=/dev/stdout)')
print('\t-q quiet; suppress output')
print('\t-y include y-data in output')
sys.exit()
elif opt in ("-i", "--ifile"):
ifile=arg
fin=open(arg,'r')
elif opt in ("-o", "--ofile"):
ofile=arg
elif opt in ("-q"):
ofile="/dev/null"
elif opt in ("-d"):
dmethod=int(arg)
elif opt in ("-f"):
f=float(arg)
elif opt in ("-w"):
w=int(arg)
elif opt in ("-p"):
plot=True
elif opt in ("-s"):
graph=True
imagefile=arg
elif opt in ("-y"):
ydata=True
data=np.loadtxt(ifile)
x=data[:,0]
y=data[:,1]
y_int=integrate.cumtrapz(y,x,initial=0)
# Collect the data and write it
if ydata:
outdata=np.array([data[:,0],data[:,1],y_int])
fmt=['%4.1f','%12.5e','%12.5e']
else:
outdata=np.array([data[:,0],y_int])
fmt=['%4.1f','%12.5e']
outdata=outdata.T
np.savetxt(ofile,outdata,fmt)
# Build the plot
fig=plt.figure()
fig.set_size_inches(16,9)
plt.plot(data[:,0],data[:,1],'-',color='black',label=ifile)
plt.plot(data[:,0],y_int,'-',color='red',label=ofile)
plt.legend()
plt.minorticks_on()
plt.grid(which='major',linestyle='-',linewidth='0.3')
plt.grid(which='minor',linestyle=':',linewidth='0.3')
if plot:
plt.show()
if graph:
fig.savefig(imagefile,dpi=120)
main(sys.argv[1:])
我得到了这个结果:
这里发生了什么?
我将幅度= 1的正弦波区分开,得到幅度非常小的余弦。当我用非常小的幅度积分余弦时,我得到幅度= 1的正弦。余弦是否也应该具有幅度= 1?