MATLAB中怎样找出一维向量的急剧变化点? 比如a=[1,2,3,2.5,4,1

MATLAB中怎样找出一维向量的急剧变化点?
比如a=[1,2,3,2.5,4,10,13,17,20,23],想在10这个地方断开,并给出10在向量a中的位置,怎么实现?

第1个回答  2013-10-11
用作差法,找出差值较大的;然后再用逻辑寻访找到位置。
第2个回答  2013-10-11
b=abs(diff(a));
[c,d]=max(b);
disp(d(1)+1)
disp(c(1))追问

实际上,我这里的向量a不止有一个拐点,给一个更具体的例子吧:
a=[1 2 2.5 3.2 5 5.1 5 5.2 5 5.3 5.2 7 11 16 17],这里的a在数值5附近基本保持不变,现在需要找出这个水平段的拐点,有什么比较简单的办法吗?

追答

clear

clc

a=[1 2 2.5 3.2 5 5.1 5 5.2 5 5.3 5.2 7 11 16 17];

n=length(a);

Ia=1:n;

pa=spline(Ia,a);


m=2;% 分成三段

Iam0=linspace(1,n,m+2);

Iam0=Iam0(2:end-1);


% fmincon 用的约束条件,但是这个函数有警告

% A=diag(ones(1,m),-1)+diag(-ones(1,m+1));A(:,end)=[];

% b=[-1;zeros(m-1,1);n];


Iam=fminsearch(@(x)sum(abs(interp1([1,x,n],ppval(pa,[1,x,n]),Ia,'linear')-a)),Iam0);%,A,b

Iam=[1,round(Iam),n];

plot(Ia,a,'*')

hold on

plot(Iam,a(Iam),'-r')

追问

谢谢啦。我只是想找到离散曲线的两个拐弯点即可,并不需要曲线拟合,你是人为地将a分成了3段了吧?

谢谢你这么细致地为我指点。我实际上只需要确定出a代表曲线的水平段的起始位置即可。

追答

对呀,变量Iam(1 x m, m=2)就是两个拐点的下标,以Iam为变量,拐点分开的三段(m+1)直线与曲线的绝对误差和为目标,找到最佳变量,即拐点。根据拐点的多少m也可以取其它整数值。

追问

谢谢啦,会给你好评啊。我想进一步知道,如果a中有2个甚至更多个水平折线,你这种找水平段的方法还适用不?要是管用的话,这真是一个绝佳办法!

刚补充的这个问题的关键点是,预先不知道到底有几个水平折线(2个,3个,4个都有可能),只需找到长度最长的那个水平折线即可!

追答

适合多个的情况,但个数只能人工控制,而且越多,计算复杂度也越高一些。如果只需“找到长度最长的那个水平折线”,这不是最佳方式,试试下面的方法:


clear

clc


a=[1 2 2.5 3.2 5 5.1 5 5.2 5 5.3 5.2 7 11 16 17 17+[5.1 5 5.2 5 5.3]];


n=length(a);

tol=0.5;% tol 为寻找水平点时,容许的数据误差

da=[abs(diff(a))<tol,0];% |差分|

j1=0;j2=0;s1=0;s2=0;

for i=1:n

    if da(i)==0

        if s2<s1

            s2=s1;%s2 最长水平段的数据个数-1

            j2=j1;%j2 最长水平段的起始下标

        end

        s1=0;j1=0;

    else

        if j1==0

            j1=i;%j1 水平段的起始下标

        end

        s1=s1+1;%s1 水平段的数据个数-1

    end

end


plot(a,'b*')

hold on

plot(j2:(j2+s2),a(j2:(j2+s2)),'-r')

    

追问

谢谢啦!

本回答被提问者采纳
相似回答