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; }

Rispondi quotando