matlab - 通过在 MATLAB 中获取上下包络来封装信号

标签 matlab interpolation envelope

我有一个在某些值附近反弹的信号。我想封装来自上方和下方的信号,如下图所示: example

如果信号仅增大或减小,则使用正在运行的 maxima 脚本效果很好:

function [out] = rMax(X)
    Y=X;
    maximum=X(1);
    for k=1:length(X)
        if X(k)<=maximum
        Y(k)=maximum;
        else
            maximum=X(k);
        end
    end
    out=Y;
end

但是,当信号交替时,我不能再使用该方法了。有没有办法在 MATLAB 或 Mathematica 中实现这一目标?

最佳答案

您可以使用movmaxmovmin根据您的需要结合适当的窗口大小 n1 > n2这两个函数是在R2016a中引入的。请查看我答案的底部,了解在 R2016a 之前工作的自行编写的替代品。

要获取上限,您可以使用:

xMax = movmax(x,[n1,n1]);
xMax = movmin(xMax,[n2,n2]);

对于下限,只需切换movminmovmax:

xMin = movmin(x,[n1,n1]);
xMin = movmax(xMin,[n2,n2]);

结果可能如下所示:

result

如果您选择n2=n1,则当数据x 出现峰值时,界限会非常严格。如果您通过使 n2 小于 n1 来选择更大的差异,您将在峰值处获得更长的直线。副作用是当信号从 1 跳到 -1 时,边界开始变远,反之亦然。如果n1选择得太高,则不会提取100左右的一小部分信号。


这是生成上图的完整代码,其中一些示例数据与您问题中的图相匹配。只需使用 n1n2 值即可查看其效果。

n1 = 20;        % for first window
n2 = 18;        % for second window

% generate sample data
t = 20:0.1:220;
x = -ones(size(t));
x(t>60&t<100) = 1;
x(t>105&t<135) = 1;
x(t>145&t<155) = 1;
x = x + 0.4*randn(size(x));

% get upper bounds
xMax = movmax(x,[n1,n1]);
xMax = movmin(xMax,[n2,n2]);

% get lower bounds
xMin = movmin(x,[n1,n1]);
xMin = movmax(xMin,[n2,n2]);

% draw figure for illustration
figure; hold on;
plot(t,x);
xlim([20,220]);
ylim([-3,3]);
plot(t,xMax,'r','LineWidth',1.1);
plot(t,xMin,'Color',[0,0.5,0],'LineWidth',1.1);

R2016a 之前

为了在 R2016a 之前的 MATLAB 版本中拥有 movminmovmax基本功能,我们可以实现自己的函数。因此,我们需要应用移动最小值(或分别移动最大值),这可以很容易地实现。为了保持与 R2016a 中函数的兼容性,我们将实现第二个参数是标量并且它是两个元素的向量的情况。这涵盖了类似于 here 的以下语法限制是 x 必须是向量。

y = movingmax(x,k)
y = movingmax(x,[kb kf])

以下是替换 movmaxmovingmax 代码:

function y = movingmax(x,n)
if length(n) > 1
    a=n(1); b=n(2);
else
    b=floor((n-1)/2); a=b+mod(n-1,2);
end
s = size(x);
xp = [ones(a,1)*x(1);x(:);ones(b,1)*x(end)];
y = zeros(size(x));
for k = 1:length(x)
    y(k) = max(xp(k:k+a+b));
end
y = reshape(y,s);

以下是替换 movminmovingmin 代码:

function y = movingmin(x,n)
if length(n) > 1
    a=n(1); b=n(2);
else
    b=floor((n-1)/2); a=b+mod(n-1,2);
end
s = size(x);
xp = [ones(a,1)*x(1);x(:);ones(b,1)*x(end)];
y = zeros(size(x));
for k = 1:length(x)
    y(k) = min(xp(k:k+a+b));
end
y = reshape(y,s);

关于matlab - 通过在 MATLAB 中获取上下包络来封装信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38301504/

相关文章:

matlab - Matlab 中向量的高斯滤波器

r - 计算数据帧中的特定模式,在 R 中进行插值

python - 使用 Scipy 插值不连续函数

java - hibernate 空间 : how to determine an envelope over lots of entries

c++ - VST GUI 推子/ slider 不更新

matlab - 将值附加到元胞数组中的多个元胞

matlab - 如何在一张图片中绘制 2 个图形?

python - 如何通过Python设置函数曲线的插值? ( blender )

python - 在 Suds python 中覆盖 Soap Envelope

matlab - 有没有办法在 MATLAB 中查看 pcode 文件 (.p) 的源代码?