最小二乘法 多項式擬合 C語言實現(引用)(附echarts畫圖代碼)

C++多階擬合(附echarts畫圖代碼)

細微修改,更通用

原文章 https://blog.csdn.net/sunshineacm/article/details/79069561

/*
    本實驗根據數組x[], y[]列出的一組數據,用最小二乘法求它的擬合曲線。
    近似解析表達式爲y = a0 + a1 * x + a2 * x^2 + a3 * x^3;(三階)
*/
#include <stdio.h>
#include <math.h>

#define maxn 5
#define rank_ 3 //階數

int main()
{

    // double x[maxn] = {0, 0.25, 0, 5, 0.75};
    // double y[maxn] = {1, 1.283, 1.649, 2.212, 2.178};
    double x[maxn] = {0, 5, 10, 15, 20};//, 25, 30, 35, 40, 45, 50, 55};
    double y[maxn] = {0, 1.27, 2.16, 2.86, 3.44};//, 3.87, 4.15, 4.37, 4.51, 4.58, 4.02, 4.64};

    double atemp[2 * rank_ + 1] = {0}, b[rank_ + 1] = {0}, a[rank_ + 1][rank_ + 1];
    int i, j, k;

    for (i = 0; i < maxn; i++)
    { 
        for (j = 0; j < rank_ + 1; j++)
        {
            b[j] += pow(x[i], j) * y[i];
        }

        for (j = 0; j < (2 * rank_ + 1); j++)
        {
            atemp[j] += pow(x[i], j);
        }
    }
    atemp[0] = maxn;
    for (i = 0; i < rank_ + 1; i++)
    { //構建線性方程組係數矩陣,b[]不變
        k = i;
        for (j = 0; j < rank_ + 1; j++)
            a[i][j] = atemp[k++];
    }
    //以下爲高斯列主元消去法解線性方程組
    for (k = 0; k < rank_ + 1 - 1; k++)
    { //n - 1列
        int column = k;
        double mainelement = a[k][k];

        for (i = k; i < rank_ + 1; i++) //找主元素
            if (fabs(a[i][k]) > mainelement)
            {
                mainelement = fabs(a[i][k]);
                column = i;
            }
        for (j = k; j < rank_ + 1; j++)
        { //交換兩行
            double atemp = a[k][j];
            a[k][j] = a[column][j];
            a[column][j] = atemp;
        }
        double btemp = b[k];
        b[k] = b[column];
        b[column] = btemp;

        for (i = k + 1; i < rank_ + 1; i++)
        { //消元過程
            double Mik = a[i][k] / a[k][k];
            for (j = k; j < rank_ + 1; j++)
                a[i][j] -= Mik * a[k][j];
            b[i] -= Mik * b[k];
        }
    }
    b[rank_ + 1 - 1] /= a[rank_ + 1 - 1][rank_ + 1 - 1]; //回代過程
    for (i = rank_ + 1 - 2; i >= 0; i--)
    {
        double sum = 0;
        for (j = i + 1; j < rank_ + 1; j++)
            sum += a[i][j] * b[j];
        b[i] = (b[i] - sum) / a[i][i];
    }
    //高斯列主元消去法結束,輸出
    printf("P(x) = %f%+fx%+fx^2%+fx^3\n\n", b[0], b[1], b[2], b[3]);
    return 0;
}

#Echarts做的圖(要先下echarts.min.js,記得勾選散點圖)
echarts畫的模擬圖
html部分

<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<title>test</title>
		<meta charset="utf-8" />
		<meta name="renderer" content="webkit" />
	</head>
	<body>
		<div id="Graph" style="width: 800px;height: 500px;">123</div>
	</body>
	<script src="echarts.min.js?ver="></script>
	<script src="index.js?ver="></script>
</html>

js部分

draw();

function f1(x) {//二階擬合
	let y = 0.230467 + 0.203691 * x - 0.002381 * x * x;
	return y;
}

function f3(x) {//三階
	let y = 0.017839 + 0.263399 * x - 0.005216 * x * x + 0.000034 * x * x * x;
	return y;
}

function f4(x) {//二階,數據減少爲5個
	return (0.027714 + 0.259114 * x - 0.004486 * x * x) // + 0.000034 * x * x * x;
}

function draw() {

	let x = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55];
	let y = [0, 1.27, 2.16, 2.86, 3.44, 3.87, 4.15, 4.37, 4.51, 4.58, 4.02, 4.64];

	let data = [];
	let data2 = []
	let data3 = []
	let data4 = []

	for (let idx in x) {
		let a = [];
		a.push(x[idx]);
		a.push(y[idx]);
		data.push(a);


		let b = [];
		b.push(x[idx]);
		b.push(f1(x[idx]))
		data2.push(b);

		let c = [];
		c.push(x[idx]);
		c.push(f3(x[idx]))
		data3.push(c);

		let c4 = [];
		c4.push(x[idx]);
		c4.push(f4(x[idx]))
		data4.push(c4);

	}

	let option = {
		tooltip: {
			trigger: 'axis',
			axisPointer: { // 座標軸指示器,座標軸觸發有效
				type: 'shadow' // 默認爲直線,可選爲:'line' | 'shadow'
			}
		},
		legend: {
			data: ['原數據', '二階', '三階', '二階5數據', "5"]
		},
		xAxis: {},
		yAxis: {},
		series: [{
				symbolSize: 10,
				data: data,
				type: 'scatter',
				name: '原數據'
			},

			{
				symbolSize: 10,
				data: data2,
				type: 'scatter',
				name: '二階'
			},

			{
				symbolSize: 10,
				data: data3,
				type: 'scatter',
				name: '三階'
			},
			{
				symbolSize: 10,
				data: data4,
				type: 'scatter',
				name: '二階5數據'
			},

		]
	};

	// 基於準備好的dom,初始化echarts實例
	var myChart = echarts.init(document.getElementById('Graph'));
	myChart.setOption(option);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章