python卷积函数_python – 理解Scipy卷积
我试图理解Scipy提供的离散卷积与人们将获得的分析结果之间的差异.我的问题是输入信号的时间轴和响应函数如何与离散卷积输出的时间轴相关?
为了尝试回答这个问题,我考虑了一个带有分析结果的例子.我的输入信号是高斯信号,我的响应函数是带阶跃函数的指数衰减.这两个信号的卷积的分析结果是修正的高斯(https://en.wikipedia.org/wiki/Exponentially_modified_Gaussian_distribution).
Scipy给出了三种卷积模式,“相同”,“完整”,“有效”.我应用了“相同”和“完整”卷积,并根据下面的分析解决方案绘制了结果.
你可以看到它们非常匹配.
当我观察到改变我的响应函数的填充域改变了卷积函数的结果时,我产生了混乱.这意味着当我设置t_response = np.linspace(-5,10,1000)而不是t_response = np.linspace(-10,10,1000)时,我得到了不同的结果,如下所示
如您所见,解决方案略有变化.我的问题是输入信号的时间轴和响应函数如何与输出的时间轴相关?我附上了我在下面使用的代码,任何帮助将不胜感激.
import numpy as np
import matplotlib as mpl
from scipy.special import erf
import matplotlib.pyplot as plt
from scipy.signal import convolve as convolve
params = {'axes.labelsize': 30,'axes.titlesize':30, 'font.size': 30, 'legend.fontsize': 30, 'xtick.labelsize': 30, 'ytick.labelsize': 30}
mpl.rcParams.update(params)
def Gaussian(t,A,mu,sigma):
return A/np.sqrt(2*np.pi*sigma**2)*np.exp(-(t-mu)**2/(2.*sigma**2))
def Decay(t,tau,t0):
''' Decay expoential and step function '''
return 1./tau*np.exp(-t/tau) * 0.5*(np.sign(t-t0)+1.0)
def ModifiedGaussian(t,A,mu,sigma,tau):
''' Modified Gaussian function, meaning the result of convolving a gaussian with an expoential decay that starts at t=0'''
x = 1./(2.*tau) * np.exp(.5*(sigma/tau)**2) * np.exp(- (t-mu)/tau)
s = A*x*( 1. + erf( (t-mu-sigma**2/tau)/np.sqrt(2*sigma**2) ) )
return s
### Input signal, response function, analytic solution
A,mu,sigma,tau,t0 = 1,0,2/2.344,2,0 # Choose some parameters for decay and gaussian
t = np.linspace(-10,10,1000) # Time domain of signal
t_response = np.linspace(-5,10,1000)# Time domain of response function
### Populate input, response, and analyitic results
s = Gaussian(t,A,mu,sigma)
r = Decay(t_response,tau,t0)
m = ModifiedGaussian(t,A,mu,sigma,tau)
### Convolve
m_full = convolve(s,r,mode='full')
m_same = convolve(s,r,mode='same')
# m_valid = convolve(s,r,mode='valid')
### Define time of convolved data
t_full = np.linspace(t[0]+t_response[0],t[-1]+t_response[-1],len(m_full))
t_same = t
# t_valid = t
### Normalize the discrete convolutions
m_full /= np.trapz(m_full,x=t_full)
m_same /= np.trapz(m_same,x=t_same)
# m_valid /= np.trapz(m_valid,x=t_valid)
### Plot the input, repsonse function, and analytic result
f1,(ax1,ax2,ax3) = plt.subplots(nrows=3,ncols=1,num='Analytic')
ax1.plot(t,s,label='Input'),ax1.set_xlabel('Time'),ax1.set_ylabel('Signal'),ax1.legend()
ax2.plot(t_response,r,label='Response'),ax2.set_xlabel('Time'),ax2.set_ylabel('Signal'),ax2.legend()
ax3.plot(t_response,m,label='Output'),ax3.set_xlabel('Time'),ax3.set_ylabel('Signal'),ax3.legend()
### Plot the discrete convolution agains analytic
f2,ax4 = plt.subplots(nrows=1)
ax4.scatter(t_same[::2],m_same[::2],label='Discrete Convolution (Same)')
ax4.scatter(t_full[::2],m_full[::2],label='Discrete Convolution (Full)',facecolors='none',edgecolors='k')
# ax4.scatter(t_valid[::2],m_valid[::2],label='Discrete Convolution (Valid)',facecolors='none',edgecolors='r')
ax4.plot(t,m,label='Analytic Solution'),ax4.set_xlabel('Time'),ax4.set_ylabel('Signal'),ax4.legend()
plt.show()
解决方法:
问题的关键在于,在第一种情况下,您的信号具有相同的采样率,而在第二种情况下,它们不具有相同的采样率.
我觉得在频域中考虑这个问题更容易,其中卷积是乘法.当您使用相同的时间轴np.linspace(-10,10,1000)创建信号和过滤器时,它们现在具有相同的采样率.对每个阵列应用傅里叶变换,得到的阵列为信号和滤波器提供相同频率的功率.因此,您可以直接将这些数组的相应元素相乘.
但是当你创建一个时间轴为np.linspace(-10,10,1000)的信号和一个时间轴为np.linspace(-5,10,1000)的滤波器时,那就不再正确了.应用傅立叶变换并乘以相应的元素不再正确,因为相应元素处的频率不相同.
让我们用你的例子来具体化.信号的变换的第一个元素(即,np.fft.fftfreq(1000,np.diff(t).mean())[1])的频率约为0.05Hz.但是对于滤波器(r),第一元件的频率约为0.066Hz.因此,将这两个元素相乘会使两个不同频率的功率相乘. (这种微妙之处就是为什么你经常看到信号处理示例首先定义采样率,然后根据它创建时间数组,信号和滤波器.)
您可以通过创建一个在[-5,10]感兴趣的时间范围内扩展的滤波器来验证这是否正确,但采样率与原始信号相同.所以使用:
t = np.linspace(-10, 10, 1000)
t_response = t[t > -5.0]
生成信号并在不同的时间范围内进行滤波,但采样率相同,因此卷积应该是正确的.这也意味着您需要修改每个数组的绘制方式.代码应该是:
ax4.scatter(t_response[::2], m_same[125:-125:2], label='Same') # Conv extends beyond by ((N - M) / 2) == 250 / 2 == 125 on each side
ax4.scatter(t_full[::2], m_full[::2], label='Full')
ax4.scatter(t_response, m, label='Analytic solution')
这将生成下图,其中分析,完整和相同的卷积匹配良好.
标签:python,scipy,convolution
python卷积函数_python – 理解Scipy卷积相关推荐
- python not函数_python 函数
1 为什么使用函数 在没有接触函数时,有时候需要将一个功能多次写,如果需要修改其中一个变量,则需要把所有实现该功能的代码一处一处改.不利于代码维护,代码量大了,组织结构也会很不清晰. 所以总结不使用函 ...
- python dump函数_python 处理 json 四个函数dumps、loads、dump、load的区别
1 .json.dumps() 函数是将一个 Python 数据类型列表(可以理解为字典)进行json格式的编码(转换成字符串,用于传播) eg, dict = {"age": & ...
- python findall函数_python正则表达式之中的findall函数是什么?
在这篇文章之中我们来了解一下关于python正则表达式的相关知识,有些朋友可能是刚刚接触到python这一编程语言,对这一方面不是特别的了解,在接下来这篇文章将会来带大家来了解关于正则表达式中的pyt ...
- python getattr函数_Python中的getattr()函数详解
在计算机编程中,自省是指这种能力:检查某些事物以确定它是什么.它知道什么以及它能做什么.自省向程序员提供了极大的灵活性和控制力. 自省(introspection),在计算机编程领域里,是指在运行时来 ...
- python describe函数_Python基础知识点梳理2,推荐收藏
接着昨天的基础知识点继续梳理,昨天的 Python基础知识梳理1 8.函数 1.定义函数: 使用关键字def来告诉python你要定义一个函数 接着指出函数名:如下面函数名是-greet_user ( ...
- python zip函数_Python zip()函数
python zip函数 Good day learners, hope that you are doing well. We discussed about Python Modulo in ou ...
- python labels函数_python——函数
1.函数的创建 函数是可以调用的(可能带有参数,也可能无参),它执行某种行动并且返回一个值.一般来说,内建的callable函数可以用来判断函数是否可调用. 1 >>> import ...
- python include函数_python 库函数
python的内建函数和库函数的区别是什么? [区别]:标准库函数都需要import xxx才能取得.内建函数都在__builtins__里面,在global里直接就能用. [补充]:1.python ...
- python islower函数_python字符串是否是小写-python 字符串小写-python islower函数-python islower函数未定义-嗨客网...
Python字符串是否是小写教程 在开发过程中,有时候我们需要判断一个 Python islower()函数详解 语法 str.islower() -> bool 参数 参数 描述 str 表示 ...
最新文章
- PHP学习笔记二: 面向对象设计
- CVPR 2016 《Object Detection from Video Tubelets with Convolutional Neural Networks》论文笔记
- Docker日志大小限制
- 深入浅出学Hive:Hive QL
- d3 line example debug 2015-05-31
- 不安和怀疑,美丽而又危险:看两位80后女艺术家的展览
- nssl1489-大冰隙2【树链剖分,线段树】
- 电力系统潮流计算matlab程序,大神们,求个电力系统潮流计算的matlab程序。
- sqlserver 批量处理数据
- 怎样学操作系统?一文带你掌握核心内容
- redis主从配置及无法连接处理
- 字符串%百分号 和 format 格式化
- PAT甲级1015 素数
- java 代码佛像_论面向组合子程序设计方法 之九 南无阿弥陀佛
- 大地坐标转换极坐标(球坐标)
- SEVERE: [FATAL] [INS-32038] The operating system group specified for central inventory
- 在linux下安装xp系统
- 复数和四元数的几何意义
- 亲宝宝APP声明遭恶意评论攻击 将不惜成本挖幕后黑手
- IT男人:四十岁是一枝花吗? 1
热门文章
- mysql 隔行记录_php mysql数据输出实现隔行变色的简单示例
- 公路交通安全设施设计细则_转让江苏公路交通工程(公路安全设施分项)二级资质(包安许)...
- java中断异常_Java中断异常 InterruptedException 的正确处理方式
- Mac 下使用 homebrew 切换不同版本 php
- 编程范式 —— 函数式编程入门
- [SHOI2009] 会场预约
- vue 父向子组件传递数据,子组件向父组件传递数据方式
- 面向对象的一些基础概念
- selenium通过autoit实现上传和下载
- HDOJ(HDU) 2186 悼念512汶川大地震遇难同胞——一定要记住我爱你