2014-04-24 2 views
0

polyfit 및 polyval을 사용하지 않고 일부 데이터에 선을 맞추려고합니다. 나는 이것을 구현하는 방법에 대한 좋은 도움을 이미 받았고 간단한 죄 함수로 작동하도록했습니다. 그러나, 내가 적합하려고하는 함수에 적용될 때, 그것은 작동하지 않습니다. 여기 내 코드는 다음과 같습니다.MATLAB 피팅 함수

clear all 
clc 

lb=0.001; %lowerbound of data 
ub=10; %upperbound of data 
step=.1; %step-size through data 
a=.03; 
la=1482/120000; %1482 is speed of sound in water and 120kHz 
ep1=.02; 
ep2=.1; 
x=lb:step:ub; 
r_sq_des=0.90; %desired value of r^2 for the fit of data without noise present 


i=1; 

for x=lb:step:ub 
    G(i,1)= abs(sin((a/la)*pi*x*(sqrt(1+(1/x)^2)-1))); 
    N(i,1)=2*rand()-1; 
    Ghat(i,1)=(1+ep1*N(i,1))*G(i,1)+ep2*N(i,1); 
    r(i,1)=x; 
    i=i+1; 
end 

x=r; 
y=G; 
V=[x.^0]; 
Vfit=[x.^0]; 


for i=1:1:1000 
    V = [x.^i V]; 
    c = V \ y; 

    Vfit = [x.^i Vfit]; 
    yFit=Vfit*c; 

    plot(x,y,'o',x,yFit,'--') 

    drawnow 
    pause 
end 

처음 두 섹션은 변수와 기능을 정의하는 것입니다. 두 번째 for 루프는 내가 적합하게 만드는 곳입니다. 보시다시피, 나는 적합을보기 위해 매 n 번째 주문 이후에 일시 중지했습니다.

+0

작동하지 않습니다. 여기에는 두 가지 문제가 있습니다. 우선, 최대 차수 다항식의 1000은 좋은 생각이 아닙니다. 약 100 개의 데이터 만 생성하므로 차수가 <100 인 다항식에 적합해야합니다. 둘째, 적합하려고하는 함수가 있습니다. 분화가 불가능하고 빠르게 진동하는 모서리. 이것은 다항식 피팅을 어렵거나 부정확하게 만듭니다. – David

+0

@ David 나는 왜 그것이 그것을 정확하게 맞추지 않는지에 대해 이해할 것을 본다. polyfit 및 polyval 함수처럼 작동하도록 구현할 수있는 함수가 더 있습니까? 아니면 함수 때문에 불가능합니까? –

답변

0

언급 한 바와 같이, 기저 함수의 다른 세트가 더 잘할 수 있습니다. 그러나 행렬 방정식을 푸는 대신 QR 인수 분해를 통한 다항식 적합성을 향상시킬 수 있습니다. 그러나 당신이 무엇을해도 상관없이 상황이 좋지 않은 문제이며, 부드러운 기초 기능을 사용하면 실제 기능에서 예리한 모서리를 정확히 재현 할 수 없습니다.

clear all 
close all 
clc 

lb=0.001; %lowerbound of data 
ub=10; %upperbound of data 
step=.1; %step-size through data 
a=.03; 
la=1482/120000; %1482 is speed of sound in water and 120kHz 
ep1=.02; 
ep2=.1; 
x=logspace(log10(lb),log10(ub),100)'; 
r_sq_des=0.90; %desired value of r^2 for the fit of data without noise present 

y=abs(sin(a/la*pi*x.*(sqrt(1+(1./x).^2)-1))); 
N=2*rand(size(x))-1; 
Ghat=(1+ep1*N).*y+ep2*N; 

V=[x.^0]; 

xs=(lb:.01:ub)'; 
Vfit=[xs.^0]; 

for i=1:1:20%length(x)-1 
    V = [x.^i V]; 
    Vfit = [xs.^i Vfit]; 
    [Q,R]=qr(V,0); 
    c = R\(Q'*y); 
    yFit=Vfit*c; 

    plot(x,y,'o',xs,yFit) 
    axis([0 10 0 1]) 
    drawnow 
    pause 
end 
+0

몇 가지 수정을 한 후이 코드로 작업하게되었습니다. 도와 주셔서 감사합니다. –

1

적합 수식이 조금 바뀌었지만 똑같은 대답을 얻었지만 신속하게 매트릭스가 단수임을 나타내는 경고 메시지가 나타납니다. 반전이 단수라는 점을 과거의 에서 계속하는 것은 의미가 없습니다.

무엇을하고 있느냐에 따라 일반적으로 변수를 변경하거나 도메인을 변경할 수 있습니다. 이것은 훨씬 나아진 것이 아니지만 약간 도움이되는 것처럼 보입니다.

커브의 첫 부분 인 이 충분히 높은 샘플링을하지 않았으므로 샘플 수를 10으로 늘 렸습니다.

가중 변수를 추가했지만 아래 코드에서 동일한 가중치로 설정되었습니다. 시도가 꼬리를 deweight하는 것은 내가 원하는만큼 많이 도움이되지 않았다.

아마 해결책은 아니지만 아마도 몇 가지 손잡이/변수가 도움이 될 것입니다.

... 
    step=.01; %step-size through data 
    ... 
    x=r; 
    y=G; 
    t=x.*sqrt(1+x.^(-2)); 
    t=log(t); 
    V=[ t.^0]; 
    w=ones(size(t)); 


    for i=1:1:1000 
     % Trying to solve for value of c 
     % c that 
     % yhat = V*c approximates y 
     % or  y = V*c 
     %  V'*y = V'*V * c 
     %   c = (V'*V) \ V'*y 
     V = [t.^i V]; 
     c = (V'*diag(w.^2)*V) \ (V'*diag(w.^2)*y) ; 

     yFit=V*c; 
     subplot(211) 
     plot(t,y,'o',t,yFit,'--') 
     subplot(212) 
     plot(x,y,'o',x,yFit,'--') 

     drawnow 
     pause 
    end 

그것은 주파수 추정의 문제가 더 좋아 보이고, 다항식과 함께 알 수없는 주파수 을 맞추려고하는 것은 터치하고 이동하는 경향이있다. 다항식 기초를 빠른 sin/cos 기초로 대치하는 것은 나쁘지 않은 것처럼 보였습니다.

V = [sin(t*i) cos(t*i) V]; 

특별히 다항식 기반을 필요로하지 않는 한, 당신은 당신의 적합을 위해 다른 잠재적으로 기능을 찾을 수있는 문제 영역에 대한 지식을 적용 할 수 있습니다, 또는 도메인이있는 당신이 적합 더 선형을 수행하기 위해 시도 .

+0

도움말 데니스에 감사드립니다! –