Passen Sie die gegebenen Daten mit der Methode der kleinsten Quadrate an

Methode der kleinsten Quadrate

Zweck der Datenanpassung:

1. Finden Sie den Näherungsausdruck y=p(x) der funktionalen Beziehung y = f(x) aus einer großen Anzahl experimenteller Daten (xi,yi) (i=0,1,2...m)

2. Die Interpolationsmethode erfordert, dass die Interpolationskurve jeden Datenpunkt strikt durchläuft. Wenn n relativ groß ist, ist das Differenzpolynom häufig ein Abschiedspolynom, das zu Schwankungen neigt.

3. Wenn es nicht erforderlich ist, dass die Näherungsfunktion y = p (x) alle Punkte durchläuft, dh yi = p (xi) i = 0,1,2 ... m, ist nur der Fehler ri = p(xi)-yi i = 0 ist erforderlich, 1,2 ... m, Minimum gemäß einem bestimmten Standard, um den Gesamtänderungstrend der ursprünglichen Funktion widerzuspiegeln und den Einfluss lokaler Schwankungen zu eliminieren, so eine Funktion y= p(x) wird als Anpassungsfunktion bezeichnet.

Grundlagen der kleinsten Quadrate

Finden Sie p(x), so dass

Fügen Sie hier eine Bildbeschreibung ein

Verfahren zur Polynomanpassung

    定义:对给定一组数据(xi,yi)  (i=0,1,2 ... m),求次数不超过n的多项式

Fügen Sie hier eine Bildbeschreibung ein

lass es befriedigen

Fügen Sie hier eine Bildbeschreibung ein

Diese Kurvenanpassung wird als Polynomanpassung bezeichnet. Wenn sie die obige Formel Pn(x) erfüllt, wird sie als Anpassungspolynom der kleinsten Quadrate bezeichnet. Wenn n = 1, wird das Polynom ersten Grades auch als Geradenanpassung bezeichnet.

Fügen Sie hier eine Bildbeschreibung ein

Aus der multivariaten Extremum-Notwendigkeitsbedingung wissen wir, dass aj erfüllt

Fügen Sie hier eine Bildbeschreibung ein

Im Augenblick
Fügen Sie hier eine Bildbeschreibung ein

In Matrixform umgewandelt als:
Fügen Sie hier eine Bildbeschreibung ein

sogenannte Normalgleichungen oder Normalgleichungen

Und hat den folgenden Satz:

Satz 1: Wenn die Punkte xi voneinander verschieden sind, dann existiert das System der Normalgleichungen und ist eindeutig.

Daten passend zu den gegebenen Daten

xi -2 -1 0 1 2
yi 0.2 0.8 2 3 4
输出拟合函数,以及平方误差

Unter Verwendung der Methode der kleinsten Quadrate zur Datenanpassung besteht der erste Schritt darin, ein normales Gleichungssystem zu konstruieren.

Die hier verwendete Methode ist:

Speichern Sie die Eingabedaten in zwei Ein-Bit-Arrays x, y, deklarieren Sie das Array tempx[2 n], speichern Sie Σx^i
und verwenden Sie den Index, um auf die Summe der entsprechenden Potenz zuzugreifen. Als nächstes deklarieren Sie das tempy[n]-Array und speichern Σxi^n
yi.

Variablen verwendet

double zhengGui[8][9] = {
    
     0 };
double x[8] = {
    
     0 };     //保存拟合数据xi
double y[8] = {
    
     0 };     //保存拟合数据yi
double tempx[15] = {
    
     0 };  //使用下标保存 xi^n的和
double tempy[9] = {
    
     0 };    //保存xi^n*yi

Vollständiger Code:

#include<iostream>
#include<math.h>
using namespace std;
double zhengGui[8][9] = {
    
     0 };
double x[8] = {
    
     0 };     //保存拟合数据xi
double y[8] = {
    
     0 };     //保存拟合数据yi
double tempx[15] = {
    
     0 };  //使用下标保存 xi^n的和
double tempy[9] = {
    
     0 };    //保存xi^n*yi
void printGuass(double a[8][9], int n) {
    
    
    for (int i = 1; i <= n; i++) {
    
    
        for (int j = 1; j <= n + 1; j++)
            printf("%12f,", a[i][j]);
        printf("\n");
    }
}
struct Max
{
    
    
    double value = 0;
    int row = 0; //保存行
    int col = 0; //保存列
};
void SelectMainE(int n)
{
    
    
    double temp;  //记录消元时的因数
    Max max;
    for (int m = 1; m <= n; m++) {
    
    
        max.value = -1000000000;
        for (int i = m; i <= n; i++)
        {
    
    
            if (abs(zhengGui[i][m]) > max.value) {
    
    
                max.value = abs(zhengGui[i][m]);
                max.row = i;
                max.col = m; //记录主元素列坐标
            }
        }
        if (max.row != m || max.col != m) {
    
    
            for (int i = m; i <= n + 1; i++) {
    
    
                swap(zhengGui[m][i], zhengGui[max.row][i]);
            }//行变换
        }
        for (int j = m + 1; j <= n; j++) {
    
    
            //消元
            temp = zhengGui[j][m] / zhengGui[m][m];
            for (int k = m; k <= n + 1; k++)
                zhengGui[j][k] -= zhengGui[m][k] * temp;
        }
    }
}
void Gauss(int n) {
    
    
    SelectMainE(n);
    //回代求解
    for (int i = n; i >= 1; i--) {
    
    //回代求解
        for (int j = i + 1; j <= n; j++)
            zhengGui[i][n + 1] -= zhengGui[i][j] * zhengGui[j][n + 1];
        zhengGui[i][n + 1] /= zhengGui[i][i];
    }
}
void GaussCol(int n) {
    
    
    printGuass(zhengGui, n);
    cout << endl;
    Gauss(n);
    for (int i = 1; i <= n; i++) {
    
    
        cout << "a" << i << "=" << zhengGui[i][n + 1] << endl;
    }
}
void getZhengGui(int m,int n) {
    
    
    //n为拟合多项式最高次数
    //m为数据个数
    zhengGui[1][1] = m + 1;
    for (int i = 1; i <= 2 * n; i++) {
    
    
        for (int j = 1; j <= m; j++) {
    
    
            tempx[i] += pow(x[j], i);
        }
    }
    for (int i = 1; i <= n + 1; i++) {
    
    
        for (int j = 1; j <= m; j++) {
    
    
            if (i == 1) {
    
    
                tempy[i] += y[j];
            }
            else {
    
    
                tempy[i] += y[j] * pow(x[j],i - 1);
            }
        }
    }
    for (int i = 2; i <= n + 1; i++) {
    
    
        //构造正规方程组的第一列,从第2行到第n+1行
        zhengGui[i][1] = tempx[i - 1];
    }
    int count = 1;
    for (int i = 2; i <= n + 1; i++) {
    
    
        //构造正规方程组的第2列到第n+1列
        //外循环控制列数,内循环控制行数
        
        for (int j = 1; j <= n + 1; j++) {
    
    
            zhengGui[j][i] = tempx[count];
            count++;
        }
        count -= n;
    }
    for (int i = 1; i <= n + 1; i++) {
    
    
        //构造第n+2列保存xi^n*yi
        zhengGui[i][n + 2] = tempy[i]; 
    }
}
void disp(int n) {
    
    
    cout << "\n拟合函数为:";
    cout << "f(x)=";
    printf("%.3lf",zhengGui[1][n + 1]);
    for (int i = 2; i <= n; i++) {
    
    
        printf("+%.3lf*",zhengGui[i][n + 1]);
        cout<< "x^" << i - 1;
    }
}
//计算平方误差
double niHeFunction(double x0,int n,int m) {
    
    
    //n表示矩阵中保存结果的最后一列
    //m为数据个数
    double sum = 0;
    sum += zhengGui[1][n + 1];
    for (int j = 2; j <= n; j++) {
    
    
        sum += pow(x0,j-1) * zhengGui[j][n + 1];
    }
    return sum;
}
void I(int m,int n) {
    
    
    //m为数据个数
    //n  拟合次数
    double sum = 0;
    for (int i = 1; i <= m; i++) {
    
    
        sum += pow(y[i] - niHeFunction(x[i], n, m),2);
    }
    cout << "\n平方误差为:" << sum;
}
void reset() {
    
    
    for (int i = 0; i < 8; i++) {
    
    
        for (int j = 0; j < 9; j++) {
    
    
            zhengGui[i][j] = 0;
            tempy[j] = 0;
        }
    }
    for (int i = 0; i < 15; i++) {
    
    
        tempx[i] = 0;
    }
}
void LeastSquares() {
    
    
    cout << "请输入需要拟合的数据的个数:";
    int m = 0;
    cin >> m;
    cout << "\n请输入xi:";
    for (int i = 1; i <= m; i++) {
    
    
        cin >> x[i];
    }
    cout << "\n请输入yi:";
    for (int i = 1; i <= m; i++) {
    
    
        cin >> y[i];
    }
    int cishu = 0;
    for (int i = 1; i <= m; i++) {
    
    
        cishu = i;
        getZhengGui(m, cishu);
        cout << "\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
        cout << "\n当前拟合函数的最高次数为:" << cishu << endl;
        //求解正规方程组
        cout << "\n正规方程组为:" << endl;
        GaussCol(cishu+1);
        disp(cishu + 1);
        I(m,cishu+1);
        cout << "\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
        reset();
    }
    
}
int main() {
    
    
    LeastSquares();
    return 0;
}

Operationsergebnis

Das Programm verwendet die Methode der kleinsten Quadrate, um die Eingabedaten anzupassen, druckt die Anpassungsfunktion mit der höchsten Ordnung 1-6 Mal aus und gibt jedes Mal die Normalmatrix aus (die Methode zum Lösen der Normalmatrix ist das Gaußsche Spaltenprinzip). Eliminierungsmethode) und führen Sie eine Fehleranalyse für jedes Anpassungsergebnis durch und drucken Sie den quadrierten Abstand aus. Der Korrektheit halber verwenden Sie Matlab, um die angegebenen 6 Anpassungsfunktionen wie folgt darzustellen:
Fügen Sie hier eine Bildbeschreibung ein

Die Eingabedaten sind derzeit:

xi   0     0.5      0.6       0.7      0.8       0.9      1.0
yi   1     1.75     1.96      2.19     2.44      2.71     3.00   

Fügen Sie hier eine Bildbeschreibung ein

Supongo que te gusta

Origin blog.csdn.net/qq_32577169/article/details/105766028
Recomendado
Clasificación