Пользователь
Регистрация: 03.03.2012
Сообщений: 11
|
C++ линейный метод наименьших квадратов
Разработка программы аппроксимации табличной функции степенным рядом( линейный метод наименьших квадратов).
использование глобальных переменных не допускается. Ошибка в расчетах. Думаю, что проблема тут
Код:
while(!strstr(s1,"EOF"))
{
fscanf(f,"%s%s",s1,s2);
x[nCount]=atof(s1);
y[nCount]=atof(s2);
nCount++;
x = (double *)realloc((void *)x,(nCount + 1)*sizeof(double));
y = (double *)realloc((void *)y,(nCount + 1)*sizeof(double));
}
ВЕСЬ ТЕКСТ
Код:
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include <math.h>
void p1();
void p2();
double * MNK(double *x, double *y, int n, int k);
void PryamoiHod(int n, double **a, double *b);
void ObratniHod(int n, double **a, double *b, double *x);
double F(double x, double *c, int k);
void main()
{
SetConsoleOutputCP(1251);
int key;
printf("\t\tАппроксимация методом НК\r\n");
printf("\tМеню:\r\n");
printf("1 - Диалоговый ввод\r\n");
printf("2 - Данные из файла\r\n");
scanf("%d", &key);
if(key == 1)
p1();
if(key == 2)
p2();
if(key!=1 && key!=2){ printf("Неверный ввод!"); exit(0);}
}
void p1()
{
int nCount;
double *x, *y;
int k;
double a,rez, *c;
printf("Введите число эксперементальных точек\r\n");
scanf("%d", &nCount);
x=(double *)malloc(nCount*sizeof(double));
y=(double *)malloc(nCount*sizeof(double));
for(int i=0; i<nCount; i++)
{
printf("\tТочка %d:\r\n", i+1);
printf("Аргумент\t"); scanf("%f", &x[i]);
printf("Функция \t");scanf("%f", &y[i]);
}
printf("Ввод окончен\r\n");
printf("Данные введены\r\n");
printf("Введите степень разложения\r\n");
printf("Большие значения степени (более 10) увеличивают точность расчёта\r\n");
scanf("%d", &k);
c=MNK(x,y,nCount,k);
printf("Введите значение аргумента\t");
scanf("%f", &a);
rez = F(a,c,k);
printf("Расчётное значение функции :\t%f\r\n", rez);
}
void p2()
{
FILE *f;
double *x, *y, *c;
int k;
if((f=fopen("dannie.txt","rb")) )
{
fseek(f,0,SEEK_END);
long fLen=ftell(f);
fseek(f,0,SEEK_SET);
char s1[16], s2[16];
int nCount=0;
x=(double *)malloc((nCount + 1)*sizeof(double));
y=(double *)malloc((nCount + 1)*sizeof(double));
while(!strstr(s2,"y"))
fscanf(f,"%s%s",s1,s2);
while(!strstr(s1,"EOF"))
{
fscanf(f,"%s%s",s1,s2);
x[nCount]=atof(s1);
y[nCount]=atof(s2);
nCount++;
x = (double *)realloc((void *)x,(nCount + 1)*sizeof(double));
y = (double *)realloc((void *)y,(nCount + 1)*sizeof(double));
}
nCount--;
fclose(f);
printf("Данные введены\r\n");
printf("Введите степень разложения\r\n");
printf("Большие значения степени (более 10) увеличивают точность расчёта\r\n");
scanf("%d",&k);
c = MNK(x, y, nCount, k);
double a,rez;
printf("Введите значение аргумента\t");
scanf("%f",&a);
rez = F(a,c,k);
printf("Расчётное значение функции :\t%f\r\n", rez);
}
}
double * MNK(double *x, double *y, int n, int k)
{
double **a =new double *[k];
double *b=new double [k];
double *c=new double [k];
for(int m=0,i,j; m < k; m++)
{
a[m]=new double[k];
for(j=0; j<k; j++)
{
a[m][j]=0;
for(i=0; i<n;i++)
a[m][j]+=pow(x[i],m+j);
}
b[m]=0;
for(i=0; i<n; i++)
b[m]+=pow(x[i],m)*y[i];
}
PryamoiHod(k,a,b);
ObratniHod(k,a,b,c);
return c;
}
void PryamoiHod(int n, double **a, double *b)
{
double v;
for(int k=0,i,j,im; k<n-1; k++)
{
im=k;
for(i=k+1; i<n; i++)
{
if(fabs(a[im][k]) < fabs(a[i][k]))
{im=i;}}
if(im!=k)
{for(j=0; j<n; j++)
{v=a[im][j];
a[im][j]=a[k][j];
a[k][j]=v;}
v=b[im];
b[im]=b[k];
b[k]=v;}
for(i=k + 1; i<n; i++)
{
v=a[i][k]/a[k][k];
a[i][k]=0;
b[i]=b[i]-v*b[k];
for(j=k+1; j<n; j++)
{a[i][j]=a[i][j]-v*a[k][j];}}}}
void ObratniHod(int n, double **a, double *b, double *x)
{
double s=0;
x[n-1]=b[n-1]/a[n-1][n-1];
for(int i=n-2,j; 0<=i; i--)
{ s=0;
for(j=i+1; j<n; j++)
{ s=s+a[i][j]*x[j];}
x[i]=(b[i]-s)/a[i][i];
}
}
double F(double x, double *c, int k)
{
double RetVal=1;
for(int i=0; i<k; i++)
RetVal+=c[i]*pow(x,i);
return RetVal;
}
|