2013-12-02 3 views
-3

Я новичок в программировании. У меня проблема, если вы знаете, можете ли вы мне помочь. Моя программа - найти коэффициенты полиномиальной интерполяции. Я использовал подпрограммы числовых рецептов в коде. Что может быть ошибкой?Ошибка ошибки сегментации при полиномиальной интерполяции

#include<stdio.h> 
#include<math.h> 
#include "nrutil.h" 
#include <stdlib.h> 
void polint(float xa[], float ya[], int n, float x, float *y, float *dy) 
{ 
int i,m,ns=1; 
float den,dif,dift,ho,hp,w; 
float *c,*d; 

dif=fabs(x-xa[1]); 
c=vector(1,n); 
d=vector(1,n); 
for (i=1;i<=n;i++) { 
    if ((dift=fabs(x-xa[i])) < dif) { 
     ns=i; 
     dif=dift; 
    } 
    c[i]=ya[i]; 
    d[i]=ya[i]; 
} 
*y=ya[ns--]; 
for (m=1;m<n;m++) { 
    for (i=1;i<=n-m;i++) { 
     ho=xa[i]-x; 
     hp=xa[i+m]-x; 
     w=c[i+1]-d[i]; 
     if ((den=ho-hp) == 0.0) nrerror("Error in routine polint"); 
     den=w/den; 
     d[i]=hp*den; 
     c[i]=ho*den; 
    } 
    *y += (*dy=(2*ns < (n-m) ? c[ns+1] : d[ns--])); 
} 
free_vector(d,1,n); 
free_vector(c,1,n); 
} 
void polcof(float xa[], float ya[], int n, float cof[]) 
{ 
void polint(float xa[], float ya[], int n, float x, float *y, float *dy); 
int k,j,i; 
float xmin,dy,*x,*y; 

x=vector(0,n); 
y=vector(0,n); 
for (j=0;j<=n;j++) { 
    x[j]=xa[j]; 
    y[j]=ya[j]; 
} 
for (j=0;j<=n;j++) { 
    polint(x-1,y-1,n+1-j,0.0,&cof[j],&dy); 
    xmin=1.0e38; 
    k = -1; 
    for (i=0;i<=n-j;i++) { 
     if (fabs(x[i]) < xmin) { 
      xmin=fabs(x[i]); 
      k=i; 
     } 
     if (x[i]) y[i]=(y[i]-cof[j])/x[i]; 
    } 
    for (i=k+1;i<=n-j;i++) { 
     y[i-1]=y[i]; 
     x[i-1]=x[i]; 
    } 
} 
free_vector(y,0,n); 
free_vector(x,0,n); 
} 
int main() { 
FILE * fp; 
fp = fopen("q1.dat", "w+"); 
int i, j, n=41; 
float x[41], f[41], cof[i]; 
for (i=0; i<=40; i++) { 
x[i]=0.05*i-1; 
f[i]=(1+tanh(2*10*x[i]))/2; 
printf("%f\t%f\n", x[i], f[i]); 
fprintf(fp, "%f\n", f[i]); } 
for (j=0; j<=40; j++) { 
polcof(x, f, n, cof); 
printf("%f\n", cof[j]); } 
fclose(fp); 
return 0; } 

-1.000000 0.000000 
-0.950000 0.000000 
-0.900000 0.000000 
-0.850000 0.000000 
-0.800000 0.000000 
-0.750000 0.000000 
-0.700000 0.000000 
-0.650000 0.000000 
-0.600000 0.000000 
-0.550000 0.000000 
-0.500000 0.000000 
-0.450000 0.000000 
-0.400000 0.000000 
-0.350000 0.000001 
-0.300000 0.000006 
-0.250000 0.000045 
-0.200000 0.000335 
-0.150000 0.002473 
-0.100000 0.017986 
-0.050000 0.119203 
0.000000 0.500000 
0.050000 0.880797 
0.100000 0.982014 
0.150000 0.997527 
0.200000 0.999665 
0.250000 0.999955 
0.300000 0.999994 
0.350000 0.999999 
0.400000 1.000000 
0.450000 1.000000 
0.500000 1.000000 
0.550000 1.000000 
0.600000 1.000000 
0.650000 1.000000 
0.700000 1.000000 
0.750000 1.000000 
0.800000 1.000000 
0.850000 1.000000 
0.900000 1.000000 
0.950000 1.000000 
1.000000 1.000000 
+0

in q1.dat i получил следующие – TheDorkSide

+0

Это может быть очень полезная статья для вас, чтобы прочитать. Мне нравится стиль ядра Linux. http://en.wikipedia.org/wiki/Programming_style – ciphermagi

+0

Смешанное использование индексации от 0 и индексация из 1. 'polint' использует 1 для' n', но массив равен 0 на 'n-1'. Nit: 'int i; float cof [i]; 'нехорошо. Возможно, OP хочет 'cof [41]' – chux

ответ

2
int i; 
float x[41], f[41], cof[i]; 

Это проблема. i не инициализируется в момент объявления cof. i должно быть инициализировано количеством плавающих элементов, которые вы хотите сохранить. Поскольку ваш цикл for выполняет итерацию от 0 до 39, вы предположительно хотите, чтобы cof имел 40 поплавков.

В качестве альтернативы (в соответствии с предварительно C99 требования), вы можете использовать таНос:

float * cof = (float *) malloc(sizeof(float)*40); 

В дополнение к соответствуя предварительно C99 требованиям, это позволит перераспределить больший размер, если это необходимо. Однако, если вы не хотите утечки памяти, это потребует освобождения через free().

Возможно, в вашем коде могут быть другие проблемы, но это, безусловно, один из них.

+2

1. C имеет [массивы переменной длины] (http://en.wikipedia.org/wiki/Variable-length_array) с C99. (Что здесь не так, так это то, что 'i' используется неинициализированным) 2. [Не выдавать результат' malloc'] (http://stackoverflow.com/questions/605845/do-i-cast-the- result-of-malloc) – Kninnug

+0

Да, это была моя глупая неосторожная ошибка написания i внутри cof, но зачем мне выделять память? Не могли бы вы уточнить, пожалуйста? – TheDorkSide

+0

Динамическое распределение памяти с помощью malloc, calloc, realloc дает вам контроль времени выполнения (в отличие от контроля времени компиляции) не только по тому, как долго он должен начинаться, но и по изменению длины. Это совершенно другой тип памяти. – ciphermagi

Смежные вопросы