Problemi con il comando interpft

di il
5 risposte

Problemi con il comando interpft

Salve a tutti,
ho un problema con il comando "interpft" di Matlab all'interno di un programma di Analisi Numerica.
Praticamente mi si chiede di scrivere il codice per confrontare i grafici di 3 tipi di interpolazione di una funzione data: quella col polinomio di Newton, quella con la spline naturale periodica e quella trigonometica proprio attraverso l'uso del comando interpft.
Il problema è che interpft non interpola bene. Non passa, cioè, attraverso tutti gli n punti attraverso cui passano le altre interpolazioni.

Questo è il codice scritto da me:

n=7;
xx=linspace(0,2*pi,50);
yv=fun(xx); %valori reali di f

x=linspace(0,2*pi,n);
y=fun(x);
pN= newton(x,y,xx);
[a,b,pS] = splineper3(x,y,xx);

x=linspace(0,2*pi-1,n-1);
y=fun(x);
pF= interpft(y,50); %%polinomio trasf di Fourier

figure(1)
plot(xx,yv,'k',xx,pN,'b',xx,pS,'g',xx,pF,'r');
title('Confronto grafici');
legend('Funzione esatta','Newton','Spline perodica','Interpolazione trigonometrica').

Qualcuno sa dirmi cosa dovrei modificare? ci deve essere per forza qualche errore nell'uno del comando interpft perchè le altre funzioni interpolano tutte bene.
Grazie anticipatamente a chi proverà ad aiutarmi.

5 Risposte

  • Re: Problemi con il comando interpft

    Quanto vale la variabile "n" nelle istruzioni:
    x=linspace(0,2*pi,n)
    
    x=linspace(0,2*pi-1,n-1)
    Inoltre, nel primo caso valuti la funzione "fun" tra (0;2*pi) ==> 0° : 360° mentre nel secondo caso la valuti tra (0;2*pi-1) ==> 302.7°

    E' giusto così?
  • Re: Problemi con il comando interpft

    No...in effetti avevo sbagliato!
    Ho modificato il secondo linspace in questo modo:
    
    x=linspace(0,2*pi-2*pi/n,n-1);
    y=fun(x);
    pF= interpft(y,50); 
    
    Praticamente nel secondo caso devo considerare l'intervallo [0,2*pi] privato del secondo estremo perchè nell'interpolazione trigonometrica non si considera essendo la funzione periodica.
    Non sono sicura che si faccia in questo modo però.
    Così l'interpolazione mi risulta passante per 5 degli 8 punti. Per gli ultimi 3 non passa ancora. Presumo proprio che l'errore stia proprio nella considerazione del giusto intervallo ma non so come modificarlo ulteriormente.
  • Re: Problemi con il comando interpft

    Dovresti pubblicare il tuo codice completo (compresa la funzione "fun"), diversamente è difficile provare ad eseguire il tuo codice e tentare di dare una risposta.
  • Re: Problemi con il comando interpft

    Questa è la funzione:
    
    function f = fun(x)
    f = 2*x.*exp(-x) + cos(2*x);
    
    Il codice rimanente dell'esercizio è questo:
    
    n=8;
    xx=linspace(0,2*pi,50);
    yv=fun(xx);
    
    x=linspace(0,2*pi,n);
    y=fun(x);
    pN= newton(x,y,xx);
    [a,b,pS] = splineper3(x,y,xx);
    
    x=linspace(0,2*pi-2*pi/n,n-1);
    y=fun(x);
    pF= interpft(y,50);  
    figure(1)
    plot(xx,yv,'k',xx,pN,'b',xx,pS,'g',xx,pF,'r');
    title('Confronto grafici');
    legend('Funzione esatta','Newton','Spline perodica','Interpolazione trigonometrica');
    
    Nel codice vengono richiamate le seguenti funzioni descritte precedentemente nel progetto:
    
    function p = newton(x,y,xx)
    n = length(x-1); 
    m = length(xx); 
    p = zeros(1,m);
    
    diff = diag(diffdivise(x,y)); 
    
    % calcolo del polinomio di Newton
    for l = 1 : m  
        x0 = xx(l); 
        p0 = diff(n);
        
        % Metodo Ruffini-Horner
        for j = n:-1:2
            p0 = p0*(x0-x(j-1)) + diff(j-1);
        end
        p(l) = p0;
    end
    
    
    function D = diffdivise(x,y)
    n = length(x-1); 
    D = zeros(n); 
    D(:,1) = y';
    for j=2:n
        for i=j:n
            D(i,j) = (D(i,j-1)-D(i-1,j-1)) / (x(i)-x(i-j+1));   
        end
    end
    
    
    function  [xxs,yys,yval] = splineper3(x,y,xval)
    n = length(x);
    
    clf;
    plot(x,y,'or');
    
    %calcolo del nuovo nodo
    x(n+1) = x(n)+x(2)-x(1);
    y(n+1) = y(2);
    
    % calcolo distanze dei nodi
    h = NaN;
    for i=1:n
        h(i) = x(i+1)-x(i);
    end
    
    % calcolo delle costanti gamma(i) e delta(i)
    gamma = NaN;
    delta = NaN;
    gamma(1) = NaN;
    delta(1) = NaN;
    for i=2:n
        gamma(i) = h(i-1)/(h(i-1)+h(i));
        delta(i) = h(i)/(h(i-1)+h(i));
    end
    
    % calcolo della matrice A
    A = zeros(n-1,n-1);
    for i=1:n-1
        A(i,i) = 2;
    end
    A(1,n-1) = gamma(2);
    A(n-1,1) = delta(n);
    for i=1:n-2
        A(i,i+1) = delta(i+1);
    end
    for i=2:n-1
        A(i,i-1) = gamma(i+1);
    end
    
    % calcolo delle differenze divise f[x(i), x(i+1), x(i+2)]
    f = NaN;
    for i=1:n-1
        nodix = [x(i) x(i+1) x(i+2)];
        nodiy = [y(i) y(i+1) y(i+2)];
        c = diffdivise(nodix,nodiy);   
        f(i) = 6*c(3,3); 
    end
    
    % calcolo dei momenti
    mu = NaN;
    muaux = A\f';
    mu(1) = 0; 
    for i=1:n-1
        mu(i+1) = muaux(i);
    end
    mu(1) = muaux(end); 
    
    % calcolo dei coefficienti alfa(i) e beta(i)
    alfa = NaN;
    beta = NaN;
    for i=1:n-1
        beta(i) = y(i) - mu(i)*h(i)^2/6;
        alfa(i) = (y(i+1)-y(i))/h(i) - h(i)*(mu(i+1)-mu(i))/6;
    end
    
    % creazione e disegno delle cubiche che compongono la spline periodica
    xxs = zeros(n-1,100);
    yys = zeros(n-1,100);
    
    hold on
    title('Spline cubica periodica');
    for j=1:n-1  
        xxs(j,:) = linspace(x(j),x(j+1),100);
        for i=1:100 
            yys(j,i) =(((x(j+1)-xxs(j,i))^3)*mu(j))/(6*h(j)) + (((xxs(j,i)-x(j))^3)*mu(j+1))/(6*h(j)) + alfa(j)*(xxs(j,i)-x(j)) + beta(j);
        end
        plot(xxs(j,:),yys(j,:),'-');
    end
    
    % calcolo dei valori della spline sui punti del vettore xval
    yval = NaN;
    if nargin<3 
        return
    else
        for i=1:length(xval)
            if xval(i)>x(n) || xval(i)<x(1)  %se xval è fuori dall'intervallo
                yval(i) = NaN;
            else
                int = 1; 
                for j=2:n-1                            
                    if xval(i)>x(j) && xval(i)<=x(j+1) 
                        int = j;                       
                    end                                
                end 
                yval(i) =(((x(int+1)-xval(i))^3)*mu(int))/(6*h(int)) + (((xval(i)-x(int))^3)*mu(int+1))/(6*h(int)) + alfa(int)*(xval(i)-x(int)) + beta(int);
                plot(xval(i),yval(i),'*r');
            end
        end
    end
    hold off
    
    Con tutto questo codice dovrebbe partire il programma e quindi uscire anche il grafico.
    Le altre funzioni però dovrebbero stare bene perchè i grafici escono corretti.
    L'errore sta sicuramente nell'utilizzo dell'iterpft perchè nel grafico quella è l'unica curva a non passare per tutti i punti.
  • Re: Problemi con il comando interpft

    Prova ad aumentare il numero di campioni che passi alla funzione "interpft" ed il numero di punti nel quali valuti la funzione "fun".

    Con:

    n=18

    e

    pF= interpft(y1,150);

    Il risultato sembra buono.
    Nella figura, i markers blu corrispondono agli 8 (n=8) campioni che usi per gli altri metodi di interpolazione, quelli rossi (n=18) quelli usato per la funzione "interpft".

    Questa è una versione aggiornata del "main" che ho usato per le prove.
    
    n=8;
    xx=linspace(0,2*pi,150);
    yv=fun(xx);
    
    x=linspace(0,2*pi,n);
    y=fun(x);
    
    % plot(xx,yv,'k')
    % hold on
    % plot(x,y,'o')
    
    pN= newton(x,y,xx);
    [a,b,pS] = splineper3(x,y,xx);
    n1=18
    x1=linspace(0,2*pi-2*pi/n1,n1-1);
    y1=fun(x1);
    % plot(x,y,'rx')
    pF= interpft(y1,150);
    % plot(xx,pF,'r')
    figure
    plot(xx,yv,'k',xx,pN,'b');
    title('Confronto grafici');
    hold on
    plot(x,y,'o')
    legend('Funzione esatta','Newton');
    figure
    plot(xx,yv,'k',xx,pS,'g');
    hold on
    plot(x,y,'o')
    title('Confronto grafici');
    legend('Funzione esatta','Spline perodica');
    figure
    plot(xx,yv,'k',xx,pF,'r');
    hold on
    
    plot(x,y,'o')
    plot(x1,y1,'d')
    title('Confronto grafici');
    legend('Funzione esatta','Interpolazione trigonometrica','old','new');
    
    

    Allegati:
    16082_ba4514f6825568f7f4342d538fb4f889.jpg
    16082_ba4514f6825568f7f4342d538fb4f889.jpg
Devi accedere o registrarti per scrivere nel forum
5 risposte