Метод наименьших квадратов
Постановка задачи:
Дана табличная функция (5 точек):
x |
0,1 |
0,3 |
0,5 |
0,6 |
0,9 |
y |
0,4 |
0,6 |
0,75 |
0,75 |
0,83 |
Требуется решить задачу аппроксимации (найти полиномы первой и второй степени методом наименьших квадратов).
Ручной счет:
Используем метод наименьших квадратов. Решаем систему Z A = B.
А) Полином второй степени.
;
Имеем систему:
B) Полином первой степени.
Имеем систему:
Реализация в Microsoft Excel:
Экспериментальные данные | |||||
x |
0,1 |
0,3 |
0,5 |
0,6 |
0,9 |
y |
0,4 |
0,6 |
0,75 |
0,75 |
0,83 |
ti |
yi |
xi |
xi2 |
yi |
xi*yi |
0,1 |
0,4 |
0,1 |
0,01 |
0,4 |
0,04 |
0,3 |
0,6 |
0,3 |
0,09 |
0,6 |
0,18 |
0,5 |
0,75 |
0,5 |
0,25 |
0,75 |
0,375 |
0,6 |
0,75 |
0,6 |
0,36 |
0,75 |
0,45 |
0,9 |
0,83 |
0,9 |
0,81 |
0,83 |
0,747 |
|
Сумма |
2,4 |
1,52 |
3,33 |
1,792 |
5 |
2,4 |
3,33 |
a0= |
0,413 |
|
2,4 |
1,52 |
1,792 |
a1= |
0,526 |
|
Реализация в Mathcad:
Метод
наименьших
квадратов
полином первой степени
Реализация в Microsoft Visual C++:
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <ctime>
#include <iomanip>
#include <math.h>
using namespace std;
void gauss(double **c, int n)
{
int i,j;
cout.precision(3);
int k;
for (k=0; k<n; k++){
for (j=n; j>=k; j--)
c[k][j]/=c[k][k];
for (i=k+1; i<n; i++)
for (j=n; j>=k; j--)
c[i][j]-=c[k][j]*c[i][k];
}
double *a;
a=new double[n*sizeof(double)];
//Обратный ход
for (i=0; i<n; i++)
a[i]=c[i][n];
for (i=n-2; i>=0; i--)
for (j=i+1; j<n; j++)
a[i]-=a[j]*(c[i][j]);
//Печать результата
cout<<"Koeff\n";
for (j=0; j<n; j++)
cout<<"a"<<j<<"="<<a[j]<<endl;
delete[] a;
}
void vvod(double *a, int n)
{
for(int i=0;i<n;i++)
cin>>a[i];
}
int main()
{
int n,i,j;
cout<<"kol-vo tochek"<<endl;
cin>>n;
double **c;
double *x, *y;
x= new double[n];
cout<<"vvod x"<<endl;
vvod(x,n);
y= new double[n];
cout<<"vvod y"<<endl;
vvod(y,n);
cout<<endl<<"prover'te koord tochek"<<endl;
for(i=0;i<n;i++)
cout<<"("<<x[i]<<","<<y[i]<<")"<<endl;
int m;
cout<<"stepen polinoma m"<<endl;
cin>>m;
m=m+1; //esli m=1, to yr-ya 2
c= new double *[m];
for(i=0;i<m;i++)
c[i]=new double[m];
int k;
double s;
for(i=0;i<m;i++)
for(j=0;j<m;j++){
s=0;
for(k=0;k<n;k++)
{
s=s+pow(x[k],(i+j));}
c[i][j]=s;}
for(i=0;i<m;i++){s=0;
for(k=0;k<n;k++)
{
s=s+y[k]*pow(x[k],i);}
c[i][m]=s;}
cout<<"Matritsa C+Y"<<endl;
for(i=0;i<m;i++)
{for(j=0;j<m+1;j++)
cout<<setw(5)<<c[i][j]<<" ";
cout<<endl;
}
cout<<endl;
gauss(c,m);
delete[] x;
delete[] y;
// for(i=0;i<n;i++)
// delete c[i];
delete[] c;
cin.get();
cin.get();
return 0;}