我想在MATLAB中将包含两个尖峰(称为Spike)的时间序列与指数内核(k)进行卷积。将卷积响应称为“calcium1”。我想使用内核的解卷积来恢复原始的尖峰(“reconSpike”)数据。我使用以下代码。
k1=zeros(1,5000);
k1(1:1000)=(1.1.^((1:1000)/100)-(1.1^0.01))/((1.1^10)-1.1^0.01);
k1(1001:5000)=exp(-((1001:5000)-1001)/1000);
k1(1)=k1(2);
spike = zeros(100000,1);
spike(1000)=1;
spike(1100)=1;
calcium1=conv(k1, spike);
reconSpike1=deconv(calcium1, k1);
问题是,在reconSpike结束时,我得到了一大块非常大的高振幅波,这些波不在原始数据中。任何人都知道为什么以及如何解决它?
谢谢!
答案 0 :(得分:1)
如果你保持尖峰矢量与k1矢量的长度相同,它对我有用。即:
k1=zeros(1,5000);
k1(1:1000)=(1.1.^((1:1000)/100)-(1.1^0.01))/((1.1^10)-1.1^0.01);
k1(1001:5000)=exp(-((1001:5000)-1001)/1000);
k1(1)=k1(2);
spike = zeros(5000, 1);
spike(1000)=1;
spike(1100)=1;
calcium1=conv(k1, spike);
reconSpike1=deconv(calcium1, k1);
你有什么理由让它们与众不同吗?
答案 1 :(得分:1)
您遇到了MATLAB的反卷积算法或浮点精度问题(或两者兼而有之)的问题。我怀疑它是浮点精度,因为在解卷积期间发生了所有的划分和减法,但是可能值得直接联系MathWorks来询问他们的想法。
根据MATLAB文档,如果[q,r] = deconv(v,u)
,则v = conv(u,q)+r
也必须保持(即deconv
的输出应始终满足此要求)。在你的情况下,这是暴力侵犯。将以下内容放在脚本的末尾:
[reconSpike1 rem]=deconv(calcium1, k1);
max(conv(k1, reconSpike1) + rem - calcium1)
我得到6.75e227,这不是零;-)接下来尝试将spike
的长度更改为6000;你会得到一个小数字(~1e-15)。逐渐增加spike
的长度;错误会变得越来越大。请注意,如果只将一个非零元素放入峰值,则不会发生此行为:错误始终为零。这说得通;所有MATLAB需要做的就是将所有内容除以相同的数字。
这是使用随机向量的简单演示:
v = random('uniform', 1,2,100,1);
u = random('uniform', 1,2,100,1);
[q r] = deconv(v,u);
fprintf('maximum error for length(v) = 100 is %f\n', max(conv(u, q) + r - v))
v = random('uniform', 1,2,1000,1);
[q r] = deconv(v,u);
fprintf('maximum error for length(v) = 1000 is %f\n', max(conv(u, q) + r - v))
输出结果为:
maximum error for length(v) = 100 is 0.000000
maximum error for length(v) = 1000 is 14.910770
我不知道你到底想要完成什么,所以很难给出进一步的建议。但我要指出的是,如果您遇到脉冲堆积的问题,并且想要提取有关每个脉冲的信息,这可能是一个棘手的问题。我知道有些人在做这样的事情,所以如果你想要一些参考资料让我知道,我会问他们。
答案 2 :(得分:1)
你应该从不期望解卷积只能撤消卷积。这是因为反卷积是ill-posed problem。
问题来自于卷积是一个完整的算子(在连续的情况下你写下一个整数int f(x) g(x-t) dx
或类似的东西)。现在,计算积分的逆( de - 卷积)是应用微分。不幸的是,差分放大了输入中的噪声。因此,如果你的积分只有轻微的误差(并且浮点不准确可能已经足够),那么你在分化后会得到完全不同的结果。
有一些可能性可以减轻这种扩增,但必须在每个应用的基础上尝试这些。