Visualizzazione dei risultati da 1 a 3 su 3
  1. #1

    C interpolazione mediante spline

    Salve a tutti...ho scritto un programma in C che mi risolve un problema di interpolazione mediante spline naturale cubica e mi valuta la spline un un insieme di punti che naturalmente stabilisco io.
    Il mio problema e' questo:
    dato che i nodi della Spline sono definiti un un determinato intervallo es: 1< nodi <7 ,se come punti in cui valutare la Spline scelgo dei punti ottenuti suddividendo l'intervallo [1,7] in 150 punti equispaziati ...quando vado a rappresentare la spline facendone il grafico col plot di Matlab ossia plot(punti in cui decido di valutare,valori corrispondenti che mi restituisce il mio programma) e' tt ok! Ottengo la mia funzione "dolce" che non contiene spigoli e che si comporta come una spline cubica naturale;se invece scelgo di suddividere l'intervallo in dei punti arbitrari mi escono degli spigoli nel grafico soprattutto negli estremi...peggio ancora quando la valuto in pochi punti ...
    ora non so' se ho sbagliato io a fare il programma (magari quando fa la valutazione) oppure se il tutto e' normale e dovuto al plot di matlab.....Se qualcuno a capito di cosa sto parlando dato che bisogna conoscere l'argomento spero mi possa aiutare...al momento evito di postare il programma

  2. #2
    Difficile aiutarti se non mostri il codice in questione...
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    codice:
    #include <stdio.h>
    #include <malloc.h>
    main ()
    
    {
    double **coeff, *x, *y, *xval, *yval, *lambda;
    int n, nn, i, j, sizef, flag , txt;
    FILE *nodi,*punti;
    
    /* Scegli come leggere la dimensione e i nodi*/
    txt=0;
    printf("Vuoi leggere la dimensione e i nodi da file(seleziona 1) o da tastiera?\n");
    scanf("%d",&txt);
    
    if (txt==1)
    	{	
    	/* Lettura matrice da file */
    	//Associo l'identificativo al file
    	nodi=fopen("nodi.txt","r");
    	fscanf(nodi,"%d",&n);
    
    	//Allocazione dei vettori dei nodi
    	x=(double *)calloc(n,sizeof(double));
    	y=(double *)calloc(n,sizeof(double));
    
    	//Allocazione del vettore dei lambda
    	lambda=(double *)calloc(n,sizeof(double));
    
    	//Lettura dei punti da interpolare
    	for(i=0;i<n;i++)
    		{
     		fscanf(nodi,"%lf",&x[i]);
     		fscanf(nodi,"%lf",&y[i]);
    		}
    	}
    else
    	{
    	/* Lettura numero di nodi */
    	printf("Inserire il numero di nodi\n");
    	scanf("%d",&n);
    
    	//Allocazione dei vettori dei nodi
    	x=(double *)calloc(n,sizeof(double));
    	y=(double *)calloc(n,sizeof(double));
    
    	//Allocazione del vettore dei lambda
    	lambda=(double *)calloc(n,sizeof(double));
    
    	//Lettura dei nodi da tastiera
    	for(i=0;i<n;i++)
    		{	
    		printf("Inserisci l'ascissa del nodo %d-smo \n",i);
    		scanf("%lf" , &x[i]);
    		printf("Inserisci l'ordinata del nodo %d-smo \n",i);
    		scanf("%lf" , &y[i]);
    		}
    	} 	
    
    
    //Allocazione della matrice dei coefficienti
    coeff=(double **)calloc(n-1,sizeof(double *));
    sizef=sizeof(double);
    for(i=0;i<n;i++)
    	{
      	coeff[i]=(double *)calloc(4,sizef);
    	}
    
    i=0;
    do
    	{
    	j=i+1;
       	do
    		{  
    		if(x[i]==x[j]) 
    			flag=0;
            	j=j+1;
    		}
    	while((j<n)&&(flag));
    	i=i+1;
    	}
    
    while((i<n-1)&&(flag));
    
    if(flag!=0)
    	{
    	//ordina i nodi con la funzione creata
    	ordina(n,x,y);
    	flag=coefficienti(n, x, y, coeff,lambda);//calcola i coeff della spline
     	
    for(i=0;i<n-1;i++)
    		{
      		for(j=0;j<4;j++)
    			{ 
    			printf("La matrice dei coefficienti della spline ha come elemento nelle posizione %d %d coeff=%f\n",i,j,coeff[i][j]);
    			}
    		}
    
    /* Scegli come leggere i punti in cui valutare la spline*/
    txt=0;
    printf("Vuoi leggere i punti in cui valutare la spline da file(seleziona 1) o da tastiera?\n");
    scanf("%d",&txt);
    
    /* Lettura numero di pt in cui valutare la spline */
    	printf("Inserire il numero di punti in cui valutare la spline\n");
    	scanf("%d",&nn);
    
    if (txt==1)
    	{
    	//apre il file dei punti in cui valutare la spline
    	punti=fopen("punti.txt","r");
    	xval=(double *)calloc(nn,sizeof(double));
    	yval=(double *)calloc(nn,sizeof(double));
    	for(i=0;i<nn;i++)
    		{
     		fscanf(punti,"%lf",&xval[i]); 
    		}
    	}
    else
    	{
    	/* Lettura numero di pt in cui valutare la spline */
    	printf("Inserire il numero di punti in cui valutare la spline\n");
    	scanf("%d",&nn);
            //Allocazione dei vettori contenenti ascisa ed ordinata dei punti di valutazione
    	xval=(double *)calloc(nn,sizeof(double));
    	yval=(double *)calloc(nn,sizeof(double));
    	//Lettura dei punti di valutazione da tastiera
    	for(i=0;i<nn;i++)
    		{	
    		printf("Inserisci l'ascissa del %d-smo punto di valutazione\n",i);
    		scanf("%lf" , &xval[i]);
    		}
    	} 	
    
    	flag=val(n,x,y[0],y[n-1],coeff,lambda[n-1],nn,xval,yval,lambda,y);//valuta la spline nei punti dati
    
    }
    else
    	{
    	printf("Due nodi sono uguali\n");
    	}
    }
    
    
    
    //calcola i coefficienti della spline
    int coefficienti(int n, double *x, double *y,double **coeff,double *lambda)
    {
    int i,flag;
    double bs[n-1],bi[n-1], diffdiv[n-1], dp[n],h[n-1];
    
    /* calcolo delle ampiezze degli intervalli */
    for (i=0;i<n;i++)
    	{
    	h[i]=x[i+1]-x[i];
    	}
    
    // costruzione delle diagonali superiore ed inferiore della matrice B
    bs[0]=1;
    for(i=1;i<n-1;i++)
    	{
       	bs[i]=h[i-1]/(x[i+1]-x[i-1]); //=delta[i]
       	bi[i-1]=1-bs[i];
    	}
    bi[n-2]=1;
    
    /* calcolo delle differenze divise del primo ordine */
    for(i=0;i<n;i++)
    	{
      	diffdiv[i]=(y[i+1]-y[i])/h[i];
    	}
    
    flag=sistema(n, bs, bi, diffdiv, lambda);
    
    //Calcolo dei coefficienti
    for(i=0;i<n-1;i++)
    	{
    	coeff[i][0]=y[i];
    	coeff[i][1]=lambda[i];
    	coeff[i][2]=(diffdiv[i]-lambda[i])/h[i];
    	coeff[i][3]=(-1)*(coeff[i][2]/h[i])-((diffdiv[i]-lambda[i+1])/h[i]*h[i]);
    	}
    
    return 1;
    }
    
    
    
    
    
    
    
    //risolve il sistema tridiagonle
    int sistema(int n, double *d, double *e, double *diffdiv, double *lambda)
    {
    int flag,i;
    double y[n],m[n-1],dp[n];
    
    
    i=1;
    dp[0]=2;
    
    do
    	{
      	m[i-1]=e[i-1]/dp[i-1];
      	dp[i]=2-m[i-1]*d[i-1];  
      	flag=dp[i];
      	i++;
     	}
    
    while((i<n)&&(flag!=0));
    
    
    //risolvo il sistema 3Bdeltaf
    y[0]=3*diffdiv[0];
    for(i=1;i<n-1;i++)	
    	{
     	y[i]=3*(e[i-1]*diffdiv[i-1]+d[i]*diffdiv[i])-(y[i-1]*m[i-1]);
    	}
    y[n-1]=3*diffdiv[n-2]-y[n-2]*m[n-2];
    
    //Calcolo i lambda
    lambda[n-1]=y[n-1]/dp[n-1];
    for(i=2;i<=n;i++)	
    	{
     	lambda[n-i]=y[n-i]-d[n-i]*lambda[n-i+1];
     	lambda[n-i]=lambda[n-i]/dp[n-i];
    	}
    
    return flag;
    }
    
    
    //ricerca l'intervallo a cui appartiene il punto
    int ricint(int n, double *x, double xval)
    {
    int i,j,m,flag;
    ;
    
    if(xval<x[0])
    	{
    	flag=0;
    	}
    else if(xval>x[n-1])
    	{
    	flag=n;
    	}
    else
    	{
    	i=0;
    	j=n-1;
     	do
    		{
      		m=(i+j)/2;//pt medio dell'intervallo di definizione
      		if(xval<x[m])
    			{
      			j=m;  
      			}	
    		else
    			{
      			i=m;
    			} 
      		}
    	while((j-i)!=1);
    
    	flag=j;
      	}// quì termina l'else
    
    return flag;
    }
    
    //funzione che valuta la spline in un vettore di punti
    int val(int n,double *x,double y1,double yn,double **coeff,double l,int nn,double *xval,double *yval, double *lambda, double *y)
    {
    int i,j, intapp;
    FILE *f_mat;
    
    for(i=0;i<nn;i++)	
    	{
    	intapp=ricint(n,x,xval[i]);
    		if(xval[i]<x[0])
    			{
                            yval[i]=y[0]+lambda[0]*(xval[i]-x[0]);
    			}
    		else if(xval[i]>x[n-1])
    			{
                            yval[i]=y[n-1]+lambda[n-1]*(xval[i]-x[n-1]);
    			}
    
    		else
    			{
    			yval[i]=coeff[intapp-1][3]*(xval[i]-x[intapp])+coeff[intapp-1][2];
    			for(j=0;j<2;j++)
    				{
    				yval[i]=yval[i]*(xval[i]-x[intapp-1])+coeff[intapp-1][1-j];
    				}
    		printf("La spline nel punto di valutazione %d-smo, cioè in corrispondenza di xval=%f vale yval=%f\n",i,xval[i],yval[i]);														
    			}
    	}
    
    //salvo sul file valori.txt
    f_mat=fopen("valori.txt","w");
    for(i=0;i<nn;i++)
    	fprintf( f_mat, "%lf\n",yval[i]);
    return 1;
    }
    
    
    
    //funzione che uso per ordinare i nodi di interpolazione e le corrispondenti ordinate
    int ordina(int n, double *x, double *y)
    {
    int i,stop,flag;
    double app;
    
    flag=1;
    stop=n-1;
    do
    	{
    	flag=0;
    	for(i=0;i<stop;i++)
    		{
        		if(x[i]>x[i+1])
    			{
    			/* scambio dei nodi consecutivi */
          			app=x[i];
          			x[i]=x[i+1];
          			x[i+1]=app; 
    			/* scambio delle ordinate corrispondenti ai nodi scambiati */
           			app=y[i];
           			y[i]=y[i+1];
           			y[i+1]=app;
          			flag=1; 
        			}
       		}
       	stop=stop-1;
    	}
    while(flag!=0);
    
    return flag;
    }

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.