您可以从线性插值角度处理此问题。假设z中没有连续的负数,你可以用interp1做到这一点:
%// Define your data
z= [...
0.000894000000000000
-0.000929000000000000
0.00101500000000000
0.000747000000000000
0.00103900000000000
0.000888000000000000
0.000828000000000000
0.000737000000000000
0.000858000000000000
-0.000723000000000000
0.000874000000000000];
keys = (1 : numel(z)).';
out = interp1(keys(z >= 0), z(z >= 0), keys, 'linear', 'extrap');
这也处理了开头和结尾都有负值的情况,extrap 标志只是外推。如果开头和结尾的值都是负数,我不确定这是否是您想要的,但我会让您自己弄清楚。
尽管如此,这种方法背后的美妙之处在于,我们提供了从 1 到我们拥有的 z 中的多个点的控制点。这些是x 点。输出y 点是z 中的值。但是,我们删除了那些为负的控制点 - z 也是如此。
接下来,我们在z 中指定从 1 到尽可能多的元素的全谱关键点,以实现最终输出。在这种情况下使用线性插值可以有效地找到由负数分隔的两点之间的平均值。
但是,如果有连续的负数,那么将会发生的情况是,我们查看在负值链开始之前为正的值,并查看在链之后为正的值,以及介于两者之间的值连续数字的运行,值被平滑地插值。我不确定这是否是你想要的,所以我把它留在这里让你弄清楚。
这是我们得到的输出:
>> format long g;
>> out
out =
0.000894
0.0009545
0.001015
0.000747
0.001039
0.000888
0.000828
0.000737
0.000858
0.000866
0.000874
或者,您也可以使用find,但需要以下假设:
此代码适用于以下假设:
-
z 开头和结尾都没有负数
-
z 中没有连续的负数。
因此:
%// Find negative values in z
ind = find(z < 0);
%// Replace each negative value with the
%// average of the values above and below each negative
z(ind) = (z(ind-1) + z(ind+1)) / 2;
上面的代码改变了z,以便将负值替换为相邻的平均值。我们再次得到:
>> format long g;
>> z
z =
0.000894
0.0009545
0.001015
0.000747
0.001039
0.000888
0.000828
0.000737
0.000858
0.000866
0.000874