Algoritmo Spline in C

di il
1 risposte

Algoritmo Spline in C

Salve ragazzi. Non so se è il posto dove fare questa domanda ma spero che qualcuno mi aiuti.
Ho creato un programma in C sull'interpolazione mediante spline ma inserendo punti e valori dati come esercizio non mi vengono i risultati richiesti.
Posto l'algoritmo (da premettere che creo due fogli di calcolo uno .h per creare la mia libreria personale e l'altro .c dove ci saranno le funzioni da me create)

QUESTA É LA LIBRERIA

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

// Legge vettore

void readarray(float x[],int n)

{
    int i;
    if(n<=0)
    {
        printf("Errore sulla dimensione \n");
    }
    else
        for(i=0;i<n;i++)
        {
            printf("ELemento[%d]=",i);
            scanf("%f",&x[i]);
        }
}


// Stampa vettore

void printarray (float x[], int n)

{
    int i=0;
    if(n<=0)
    {
        printf("Errore sulla dimensione \n");
    }
    else
        printf("La soluzione e':\n");
    for(i=0;i<n;i++)
        printf("Elemento[%d]=%f\n",i,x[i]);
}

//ordina

void order(float x[],float y[],int n)
{
	float temp;
    
	int k,i,j;
    
	for(i=0;i<n;i++)
	{
		temp=x[i];
		k=i;
		for(j=i+1;j<n;j++)
		{
			if(x[j]<temp)
			{
				temp=x[j];
				k=j;
			}
		}
		
		temp=x[i];
		x[i]=x[k];
		x[k]=temp;
        
		temp=y[i];
		y[i]=y[k];
		y[k]=temp;
	}
}


// Costruzione 

void costruzione (float x[],float y[],int n, float D[], float L[], float U[], float B[],float diff[])

{
	int i;
	float h[100];
    
	for(i=1;i<n;i++)
		h[i]=x[i]-x[i-1];
    
	for(i=1;i<n;i++)
		diff[i]=(y[i]-y[i-1])/h[i];
	
	D[0]=2;
	U[0]=1;
	L[0]=0;
	
	for(i=1;i<n-1;i++)	
	 {
		D[i]=2;
		U[i]=h[i]/(h[i]+h[i+1]); 
		L[i]=1-U[i];
         }
	   
	D[n-1]=2;
	U[n-1]=0;
	L[n-1]=1;

	B[0]=3*diff[1];
	
	for(i=1;i<n-1;i++)
	B[i]=3*((L[i]*diff[i])+(U[i]*diff[i+1]));
	
	B[n-1]=3*diff[n-1];
}


// Gauss per tridiagonali

void gauss3d (float D[],float U[],float L[],float b[],int n)

{
    int i,k;
    float molt=0;
    
    molt=L[1]/D[0];
    
    L[1]=0;

    D[1]=D[1]-(molt*U[0]);

    b[1]=b[1]-(molt*b[0]);
    
    for(k=2;k<n;k++)
    {
        molt=L[k]/D[k-1];
        L[k]=0;
        
        D[k]=D[k]-(molt*U[k-1]);

        b[k]=b[k]-(molt*b[k-1]); // aggiornamento termine noto
    }
    
}


// Risoluzione con backsub per sistemi tridiagonali

void backsub3d (float D[],float U[],float B[],float X[],int n)

{
    int i;
    
    X[n-1]=B[n-1]/D[n-1];
    
    for(i=n-2;i>=0;i--)
    {
        X[i]=(B[i]-(U[i]*X[i+1]))/D[i];
    }
    
}

// Differenze divise 

void diffdiv (float diff[],float diff2[],float diff3[],float x[],float y[],float X[],int n)

{
	int i;
	
	for(i=0;i<n;i++)
	{
		diff2[i]=(diff[i+1]-X[i])/(x[i+1]-x[i]);
	}

	for(i=0;i<n;i++)
	{
		diff3[i]=X[i+1]+X[i]-2*diff[i+1];
	}
}

// valutazione

void valuta (float x[],float y[],float X[],float diff2[],float diff3[],int n)
{
	float c, val;
	int k,i;

	printf("In quale punto vuoi valutare il polinomio?\nx=:");
	scanf("%f",&c);

	if(c<x[0])
		val=y[0]+(X[0]*(c-x[0]));
	else 
	if(c>x[n-1])
		val=y[n-1]+(X[n-1]*(c-x[n-1]));
	else
	{
		for(i=1;i<n;i++)
			{
				if(c<x[i])
				k=i;
			}
		val=(y[k-1]+(X[k-1]*(c-x[k-1]))+(diff2[k-1]*pow(c-x[k-1],2))+(diff3[k-1]*(c-x[k])*pow(c-x[k-1],2)));
	}
	printf("s(%f)=%f\n", c, val);
}

QUESTO É IL .C

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include "spline1.h"

main()

{
        int i,j,k,n;
        float x[100],y[100],U[100],B[100],L[100],D[100],b[100],diff[100],X[100];
    	float diff2[100],diff3[100];
    
        //Inserisco dimenzione nodi e valori
        printf("Inserire dimensione:");
    	scanf("%d",&n);
    
    	printf("\n");
    
    	printf("Inserire i nodi x:\n");
    	readarray(x,n);
    
    	printf("\n");
    
    	printf("Inserire i valori corrispondenti dei nodi y:\n");
    	readarray(y,n);
    
    	printf("\n");
    
        //ordino i nodi
        order(x,y,n);
    
        //costruisco la matrice tridiagonale
    	costruzione (x,y,n,D,L,U,B,diff);
    
        //Triangolarizzo la matrice tridiagonale
    	gauss3d (D,U,L,b,n);
    
        //Risolvo il sistema calcolandomi i lambda(X)
    	backsub3d (D,U,B,X,n);
	
        //creo le differenze divise
        diffdiv(diff,diff2,diff3,x,y,X,n);
  
        //Valuto il polinomio mediante Hermite
        valuta(x,y,X,diff2,diff3,n);
	
    
}
    

GRAZIE PER UN'EVENTUALE RISPOSTA.

1 Risposte

  • Re: Algoritmo Spline in C

    Purtroppo non ho assolutamente il tempo di guardare il tuo codice nel dettaglio, anche perché sfortunatamente non hai usato i tag Code e risulta doppiamente difficile leggerlo.
    Tuttavia, ritengo doveroso fornirti almeno alcuni consigli di engineering, data anche la sezione scelta:

    1) Non inserire mai, per nessun motivo, implementazioni di funzioni e altro codice in uno header .h - ribadisco, mai. Si tratta di una pratica totalmente deprecata, e dovrebbe esserlo anche a livello scolastico. Sorgenti separati .c possono essere linkati con estrema facilità, da command line, entro una qualsiasi IDE (creando un "project"), tramite makefile o cmake...

    2) Prima di cimentarsi in qualsiasi calcolo floating point IEEE 754 usando il linguaggio C, è fondamentale avere studiato almeno questo, seguito da , e sperabilmente da un testo di analisi numerica.

    3) Oltre al punto precedente, è opportuno anche familiarizzare con le numerose implementazioni di riferimento in linguaggio C, trattandosi di un algoritmo estremamente comune. Google is your friend.

    4) Già implicito nell'introduzione, è opportuno formattare il codice con gli appositi tag per aumentarne la leggibilità, e la probabilità di ottenere anche una risposta di dettaglio, a complemento dei consigli (comunque importanti) appena ricevuti.
Devi accedere o registrarti per scrivere nel forum
1 risposte