我正在尝试创建一些代码,这些代码会执行以下操作:在时间序列中,当v从负到正交叉时,这与其他过零点(左右方向)相隔至少4天,如果我从右边拿8个元素(从过零点开始),至少80%的日子是正面的,如果我向左边拿6个元素(从过零点开始),至少60%的日子是负。符合这些条件的系列会被标记或保存在该位置。
感谢您的帮助..
v=[-1 2 3 -9 -8 -6 -7 -9 -3 -2 -5 -6 -3 1 6 8 5 9 7 4 5 6 -5 -7 2 5 3 2 -2 -1 -5 -4 1 4 3 5 6 3 4 3 -4 5]
通过这个程序,当值从正变为负时,我可以提取位置,反之亦然。
vexample=v;
vexample(vexample >= 0) = 1;
vexample(vexample < 0) = -1;
z = vexample > 0;
id = find([true;diff(vexample.') ~= 0]);
k = diff([id;numel(vexample)+1]);
out = -k;
out(z(id)) = k(z(id));
clear id k vexample z
out = -1 2 -10 9 -2 4 -4 8 -1 1
现在,我正在尝试检测符合条件的系列部分,但我遇到了问题
答案 0 :(得分:2)
老实说,我认为你自己和这个问题的读者比你需要的更加困惑。看起来你已经从上面的代码中精通了MATLAB,所以我对你的回答只是将它分解成部分。
首先找到零交叉的所有索引(我认为这是id是什么?)
现在你可以使它变得简单并消除彼此之间的索引。使用for循环和if语句使向量无效(更接近4)。在for循环通过后,删除它们。
说实话,我不清楚你在这部分甚至试图做什么:
如果我把8个元素(从零交叉点)带到右边,至少是 80%的日子是积极的,如果我在左边拿6个元素 (从过零点开始),至少60%的日子是负面的。
但是对于一些基本的if语句来说这应该很容易..
所有很酷的编程项目都是按照婴儿步骤完成的,这就是我建议你开始的方式。
答案 1 :(得分:0)
这非常令人困惑。我实际上发现通常最好退后一步,重新定义我需要的代码/数学,而不是单词。例如,而不是
8个元素(从过零点开始)到右边,至少80%的日子都是正面的
尝试
%Find all N such that
sum(sign(v((N):(N+7)))) >= ceil(0.60 * 8)
这自然会引发一些问题,例如(N+7)
或(N+8)
。
我已经为你的要求段做了一个简单的尝试:
%Given the input
v=[-1 2 3 -9 -8 -6 -7 -9 -3 -2 -5 -6 -3 1 6 8 5 9 7 4 5 6 -5 -7 2 5 3 2 -2 -1 -5 -4 1 4 3 5 6 3 4 3 -4 5];
%Find all N such that
% **** low to high zero crossing
% (1) v(N) > 0
% (2) v(N-1) < 0
% **** +/- 4 days of no zero crossings
% (3) all(v((N-5):(N-1)) < 0)
% (4) all(v((N):(N+4)) > 0)
% **** +/- 8 days of rare zeros crossings
% (3) sum(sign(v((N-8):(N-1)))) <= - floor(0.60 * 8)
% (4) sum(sign(v( (N):(N+7)))) >= ceil(0.80 * 8)
此时(一旦你同意我的翻译),编写适当的循环非常容易:
%Simple loop
maskResult = false(size(v));
vSign = sign(v);
for ix = 9:(length(v)-8)
if ...
all(vSign((ix-5):(ix-1)) < 0) && ...
all(vSign((ix):(ix+4)) > 0) && ...
sum(sign(vSign((ix-8):(ix-1)))) <= - floor(0.60 * 8) && ...
sum(sign(vSign( (ix):(ix+7)))) >= ceil(0.80 * 8)
maskResult(ix) = true;
end
end
您可以使用
查看结果find(maskResult) %returns 14, indicating the -3 -> 1 transition