# 数值方法 最小二乘法拟合多项式

16 篇文章 0 订阅

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

import java.util.Scanner;

public class shujvnihe {
static final public int N = 20;
static public double x[] = new double[N];
static public double y[] = new double[N];
static public double l[] = new double[N];
static public double xx[] = new double[N];
static public double yy[] = new double[N];
static public double juzhen[][] = new double[N][N + 1];

static public double e[] = new double[N];

static public int n;

static public void display() {
for (int i = 1; i <= n + 1; i++) {
for (int j = 1; j <= n + 1 + 1; j++)
System.out.print(juzhen[i][j] + " ");
System.out.println();
}
}

static public double x_n(double x, int n) {

double mul = 1;
for (int i = 1; i <= n; i++) {
mul *= x;
}
return mul;
}

static public double x_y(double y, double x, int n) {

return y *= x_n(x, n);
}

static public void gaosi(int n) {
//标记列号
for (int i = 1; i <= n; i++)
juzhen[0][i] = i;
juzhen[0][n + 1] = 0;

//display();

//消元
for (int k = 1; k < n; k++) {
//找绝对值最大的
double max = Math.abs(juzhen[k][k]);
int p = k;
int q = k;
for (int i = k; i <= n; i++) {
for (int j = k; j <= n; j++) {
if (Math.abs(juzhen[i][j]) > max) {
max = Math.abs(juzhen[i][j]);
p = i;
q = j;
}
}
}
//交换行
for (int i = 1; i <= n + 1; i++) {
double temp = juzhen[p][i];
juzhen[p][i] = juzhen[k][i];
juzhen[k][i] = temp;

}
//交换列
for (int i = 0; i <= n; i++) {
double temp = juzhen[i][q];
juzhen[i][q] = juzhen[i][k];
juzhen[i][k] = temp;
}

for (int i = k + 1; i <= n; i++) {
l[i] = juzhen[i][k] / juzhen[k][k];
for (int j = 1; j <= k; j++) {
juzhen[i][j] = 0;
}
for (int j = k + 1; j <= n + 1; j++) {
juzhen[i][j] = juzhen[i][j] - l[i] * juzhen[k][j];
}
//display();
}
}

//回代
y[n] = juzhen[n][n + 1] / juzhen[n][n];
for (int k = n - 1; k >= 1; k--) {
double sum = 0;

for (int j = k + 1; j <= n; j++) {
sum += juzhen[k][j] * y[j];
}
y[k] = (juzhen[k][n + 1] - sum) / juzhen[k][k];
}

//由y得到x
for (int i = 1; i <= n; i++) {
x[(int) juzhen[0][i]] = y[i];
}
//输出解
for (int i = 1; i <= n; i++) {
System.out.println("a[" + (i - 1) + "]=" + x[i]);
}
}

public static void main(String[] args) {
//输入
int m;
System.out.println("输入点数：");
Scanner scanner=new Scanner(System.in);
m = scanner.nextInt();
System.out.println("输入x,y");
for (int i = 0; i < m; i++) {
xx[i] = scanner.nextDouble();
yy[i] = scanner.nextDouble();
}
System.out.println("\"输入拟合次数：\"");
n = scanner.nextInt();

//计算矩阵
juzhen[1][1] = m;

for (int i = 1; i <= n + 1; i++) {
for (int j = i; j <= n + 1; j++) {
double sum1 = 0, sum2 = 0;
for (int k = 0; k < m; k++) {
sum1 += x_n(xx[k], i + j - 2);
sum2 += x_y(yy[k], xx[k], i - 1);
}
juzhen[i][j] = juzhen[j][i] = sum1;
juzhen[i][n + 1 + 1] = sum2;
}
}
display();

//高斯主元素
gaosi(n + 1);

//输出拟合多项式
System.out.println("拟合多项式为：");
for (int i = 1; i <= n + 1; i++) {
if (i == 1) {
System.out.print(x[i]);
continue;
}
if (x[i] > 0)
System.out.print("+");
System.out.print(x[i] + "x^" + (i - 1));
}
System.out.println();

//求平方误差
double esum = 0;
for (int j = 1; j <= m; j++) {
for (int i = 1; i <= n + 1; i++) {
e[j] += x[i] * x_n(xx[j - 1], i - 1);
}
esum += (e[j] - yy[j - 1]) * (e[j] - yy[j - 1]);
}

System.out.println("平方误差:" + esum);

}
}



• 0
点赞
• 0
评论
• 4
收藏
• 一键三连
• 扫一扫，分享海报

07-03 1万+

04-15 4355
03-08 1万+
03-17 1696
07-10 1万+
08-21 9429
04-01 7121
02-28
06-28