package lab8;
import java.util.*;
import java.awt.*;
import javax.swing.*;
public class Interpolation {
JFrame frame;
Lines lines;//画单项式基底得到的曲线
Lines1 lines1;//画牛顿插值得到的曲线
Lines2 lines2;//画拉格朗日插值得到的曲线
/**
* 单项式基底,拉格朗日插值,牛顿插值
*/
double t[] = { 0d, 1d, 2d, 3d, 4d };
double y[] = { 0d, 11, 29d, 65d, 125d };
double y1[] = { 0d, 11, 29d, 65d, 125d };
double y2[] = { 0d, 11, 29d, 65d, 125d };
double[][] A = new double[5][5];
double[][] A1 = new double[5][5];
double[] x = new double[5];
double[] x1 = new double[5];
void Monomial(double[] t, double[] y) {
// 初始化范德蒙矩阵a;
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= 4; j++) {
A[i][j] = Math.pow(t[i], j - 1);
}
}
double[][] M = new double[5][5];
double num = 0, num1 = 0;
int p = 0;
for (int k = 1; k < 4; k++) {
// 找出p
double max = -1;
for (int j = k; j <= 4; j++) {
if (Math.abs(A[j][k]) > max) {
max = Math.abs(A[j][k]);
p = j;
}
}
// 交换
if (k != p) {
for (int l = 1; l <= 4; l++) {
num = A[k][l];
A[k][l] = A[p][l];
A[p][l] = num;
}
// B交换
num1 = y[k];
y[k] = y[p];
y[p] = num1;
}
// 得到M[][]
if (A[k][k] != 0) {
for (int i = k + 1; i <= 4; i++) {
M[i][k] = A[i][k] / A[k][k];
}
// 得到A[][]
for (int j = k; j <= 4; j++) {
for (int i = k + 1; i <= 4; i++) {
A[i][j] = A[i][j] - M[i][k] * A[k][j];
}
}
// 得到B[][]
for (int h = k + 1; h <= 4; h++) {
y[h] = y[h] - y[k] * M[h][k];
}
}
}
//回代求x
for (int j = 4; j >= 1; j--) {
if (A[j][j] == 0)
return;
x[j] = y[j] / A[j][j];
for (int i = 1; i <= j - 1; i++) {
y[i] = y[i] - A[i][j] * x[j];
}
}
}
// 牛顿插值
void Newton(double[] t, double[] y) {
// 将下三角矩阵每个值初始化为1
for (int i = 1; i <= 4; i++)
for (int j = 1; j <= i; j++)
A1[i][j] = 1;
// 求得下三角矩阵
for (int i = 1; i <= 4; i++) {
for (int j = 2; j <= i; j++) {
for (int k = 1; k < j; k++) {
A1[i][j] = A1[i][j] * (t[i] - t[k]);
}
}
}
// 前代法求得系数矩阵x1
for (int j = 1; j <= 4; j++) {
if (A1[j][j] == 0)
return;
x1[j] = y1[j] / A1[j][j];
for (int i = j + 1; i <= 4; i++) {
y1[i] = y1[i] - A1[i][j] * x1[j];
}
}
}
void run() {
frame = new JFrame("曲线图");
frame.setLayout(new GridLayout(1, 3));
Monomial(t, y);//求x[],
lines = new Lines(t, y2, x);//画单项式基底得到的曲线
lines.setSize(400, 400);
frame.add(lines);
Newton(t, y1);//求x1[]
lines1 = new Lines1(t, y2, x1);//画牛顿插值得到的曲线
lines1.setSize(400, 400);
frame.add(lines1);
lines2 = new Lines2(t, y2);//画拉格朗日插值得到的曲线
lines2.setSize(400, 400);
frame.add(lines2);
frame.setSize(1200, 400);
frame.setVisible(true);
frame.setLocation(75, 100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new Interpolation().run();
}
}
//单项式基底
class Lines extends JPanel {
double t[], y[], x[];
public Lines(double[] t, double[] y, double[] x) {
this.t = t;
this.y = y;
this.x = x;
}
public void paint(Graphics g) {
double x1, y1;
g.drawLine(50, 30, 50, 320);//画x轴
g.drawLine(30, 300, 370, 300);//画y轴
//标注x轴
g.drawString("0", 43, 310);
g.drawLine(110, 298, 110, 302);
g.drawString("1", 108, 315);
g.drawLine(170, 298, 170, 302);
g.drawString("2", 168, 315);
g.drawLine(230, 298, 230, 302);
g.drawString("3", 228, 315);
g.drawLine(290, 298, 290, 302);
g.drawString("4", 288, 315);
g.drawLine(350, 298, 350, 302);
g.drawString("5", 348, 315);
//标注y轴
g.drawLine(48, 250, 52, 250);
g.drawString("30", 25, 255);
g.drawLine(48, 200, 52, 200);
g.drawString("60", 25, 205);
g.drawLine(48, 150, 52, 150);
g.drawString("90", 25, 155);
g.drawLine(48, 100, 52, 100);
g.drawString("120", 25, 105);
g.drawLine(48, 50, 52, 50);
g.drawString("150", 25, 55);
g.drawString("单项式基底", 150, 350);
g.setColor(Color.red);
for (int i = 1; i < t.length; i++) {// 画出各个点
x1 = t[i] * 60 + 50;
y1 = y[i] * 50 / 30;
g.drawOval((int) x1, (int) (300 - y1), 4, 4);
}
g.setColor(Color.black);
for (double i = 50; i < 370; i++) {// 根据多项式系数,画曲线
y1 = 0;
for (int j = 1; j < x.length; j++) {
y1 += x[j]
* Math.pow(((double) ((i - 50) / 60)), (double) (j - 1));// 求y
}
y1 = y1 * ((double) 50 / (double) 30);
g.drawLine((int) i, 300 - ((int) y1), (int) i, 300 - ((int) y1));
}
}
}
//牛顿插值
class Lines1 extends JPanel {
double t[], y[], x[];
public Lines1(double[] t, double[] y, double[] x) {
this.t = t;
this.y = y;
this.x = x;
}
public void paint(Graphics g) {
double x1, y1;
g.drawLine(50, 30, 50, 320);
g.drawLine(30, 300, 370, 300);
g.drawString("0", 43, 310);
g.drawLine(110, 298, 110, 302);
g.drawString("1", 108, 315);
g.drawLine(170, 298, 170, 302);
g.drawString("2", 168, 315);
g.drawLine(230, 298, 230, 302);
g.drawString("3", 228, 315);
g.drawLine(290, 298, 290, 302);
g.drawString("4", 288, 315);
g.drawLine(350, 298, 350, 302);
g.drawString("5", 348, 315);
g.drawLine(48, 250, 52, 250);
g.drawString("30", 25, 255);
g.drawLine(48, 200, 52, 200);
g.drawString("60", 25, 205);
g.drawLine(48, 150, 52, 150);
g.drawString("90", 25, 155);
g.drawLine(48, 100, 52, 100);
g.drawString("120", 25, 105);
g.drawLine(48, 50, 52, 50);
g.drawString("150", 25, 55);
g.drawString("牛顿插值", 150, 350);
g.setColor(Color.red);
for (int i = 1; i < t.length; i++) {// 画出各个点
x1 = t[i] * 60 + 50;
y1 = y[i] * 50 / 30;
g.drawOval((int) x1, (int) (300 - y1), 4, 4);
}
g.setColor(Color.black);
for (double i = 50; i < 370; i++) {// 根据多项式系数,画曲线
y1 = 0;
for (int j = 1; j < x.length; j++) {
double temp = 1, te = 0;
for (int k = 1; k < j; k++) {
temp = temp * ((double) ((i - 50) / 60) - t[k]);
}
te = temp * x[j];
y1 = y1 + te;
}
y1 = y1 * ((double) 50 / (double) 30);
g.drawLine((int) i, (int) (300 - y1), (int) i, (int) (300 - y1));
}
}
}
//拉格朗日插值
class Lines2 extends JPanel {
double t[], y[];
public Lines2(double[] t, double[] y) {
this.t = t;
this.y = y;
}
public void paint(Graphics g) {
double x1, y1;
g.drawLine(50, 30, 50, 320);
g.drawLine(30, 300, 370, 300);
g.drawString("0", 43, 310);
g.drawLine(110, 298, 110, 302);
g.drawString("1", 108, 315);
g.drawLine(170, 298, 170, 302);
g.drawString("2", 168, 315);
g.drawLine(230, 298, 230, 302);
g.drawString("3", 228, 315);
g.drawLine(290, 298, 290, 302);
g.drawString("4", 288, 315);
g.drawLine(350, 298, 350, 302);
g.drawString("5", 348, 315);
g.drawLine(48, 250, 52, 250);
g.drawString("30", 25, 255);
g.drawLine(48, 200, 52, 200);
g.drawString("60", 25, 205);
g.drawLine(48, 150, 52, 150);
g.drawString("90", 25, 155);
g.drawLine(48, 100, 52, 100);
g.drawString("120", 25, 105);
g.drawLine(48, 50, 52, 50);
g.drawString("150", 25, 55);
g.drawString("拉格朗日插值", 150, 350);
g.setColor(Color.red);
for (int i = 1; i < t.length; i++) {// 画出各个点
x1 = t[i] * 60 + 50;
y1 = y[i] * 50 / 30;
g.drawOval((int) x1, (int) (300 - y1), 4, 4);
}
g.setColor(Color.black);
for (double i = 50; i < 370; i++) {// 根据多项式系数,画曲线
double z = (double) ((i - 50) / 60);
y1 = 0;
double[] l = new double[t.length];
for (int n = 1; n < t.length; n++) {
l[n] = 1;
}
for (int j = 1; j < t.length; j++) {
for (int k = 1; k < t.length; k++) {
if (k != j) {
l[j] = l[j] * (z - t[k]) / (t[j] -