计算方法/数值计算 实验一
计算方法/数值计算 实验一
问题重述
问题分析
将Lagrange多项式插值函数写成:
L
n
(
x
)
=
∑
k
=
0
n
[
y
k
∏
j
=
0
;
j
≠
k
n
(
x
−
x
j
x
k
−
x
j
)
]
L_{n}(x) = \sum^{n}_{k=0}[y_k\prod^{n}_{j=0;j\neq k}(\frac{x-x_j}{x_k-x_j})]
Ln(x)=k=0∑n[ykj=0;j=k∏n(xk−xjx−xj)]
先固定k,通过内循环求得:
l
n
(
x
)
=
∏
j
=
0
;
j
≠
k
n
(
x
−
x
j
x
k
−
x
j
)
l_n(x)=\prod^{n}_{j=0;j\neq k}(\frac{x-x_j}{x_k-x_j})
ln(x)=j=0;j=k∏n(xk−xjx−xj)
再通过外循环求得:
L
n
(
x
)
=
∑
k
=
0
n
y
k
l
n
(
x
)
L_n(x) = \sum^{n}_{k=0}y_kl_n(x)
Ln(x)=k=0∑nykln(x)
实现代码
MATLAB实现
MATLAB代码
k = input('Enter k(define the test function): ');
n = input('Enter n(define the number of data point): ');
x_arr = linspace(0, 1, n + 1);
y_arr = abs(sin(k * pi * x_arr));
PLOT_POINT_NUM = 100;
x_plot_arr = linspace(0, 1, PLOT_POINT_NUM);
y_plot_arr = zeros(1, PLOT_POINT_NUM);
for m = 1: PLOT_POINT_NUM
for p = 1: n + 1
y_temp = y_arr(p);
for q = 1: n + 1
if q ~= p
y_temp = y_temp * ((x_plot_arr(m) - x_arr(q))/(x_arr(p) - x_arr(q)));
end
end
y_plot_arr(m) = y_plot_arr(m) + y_temp;
end
end
plot(x_plot_arr, y_plot_arr, 'r');
title('raw function and lagrange interpolating function')
hold on
y_plot_true_arr = abs(sin(k * pi * x_plot_arr));
plot(x_plot_arr, y_plot_true_arr, 'b');
MATLAB实验结果
Python实现
Python代码
import numpy as np
from matplotlib import pyplot as plt
import math
PLOT_POINT_NUM = 100
k = int(input('Enter k(define the test function): '))
n = int(input('Enter n(define the number of data point): '))
x = [i / n for i in range(n)]
y = list(map(lambda i: abs(math.sin(k * math.pi * i)), x))
x_test = [i / PLOT_POINT_NUM for i in range(PLOT_POINT_NUM)]
y_plot = np.zeros_like(x_test)
y_test = list(map(lambda i: abs(math.sin(k * math.pi * i)), x_test))
for m in range(PLOT_POINT_NUM):
for p in range(n):
y_temp = y[p]
for q in range(n):
if q != p:
y_temp *= ((x_test[m] - x[q]) / (x[p] - x[q]))
y_plot[m] += y_temp
plt.plot(x_test, y_test, 'b')
plt.plot(x_test, y_plot, 'r')
plt.show()
Python实现结果
Java实现
Java代码
- 测试实现类(TestLagrange.java)
package lagrange;
import java.util.Scanner;
public class TestLagrange {
private static final double PI = 3.1415926;
private static final int PLOT_POINT_NUM = 100;
private static int k;
private static double testFunction(double x) {
return Math.abs(Math.sin(k * PI * x));
}
private static void initArray(double[] xTempArray, int n) {
for (int i = 0 ; i < xTempArray.length ; i++) {
xTempArray[i] = 1.0 / n * i;
}
}
private static double[] getArray(double[] xTempArray) {
double[] yTempArray = new double[xTempArray.length];
for (int i = 0 ; i < xTempArray.length ; i++) {
yTempArray[i] = testFunction(xTempArray[i]);
}
return yTempArray;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter k(define the test function): ");
k = scanner.nextInt();
System.out.print("Enter n(define the number of data point): ");
int n = scanner.nextInt();
String funcExpression = "y = abs(sin(" + k + " * PI * x))";
double[] xArray = new double[n];
initArray(xArray, n);
double[] yArray = getArray(xArray);
double[] xTestArray = new double[PLOT_POINT_NUM];
initArray(xTestArray, PLOT_POINT_NUM);
double[] yTestArray = new double[xTestArray.length];
for (int m = 0 ; m < xTestArray.length ; m++) {
for (int p = 0 ; p < xArray.length ; p++) {
double yTemp = yArray[p];
for (int q = 0 ; q < xArray.length ; q++) {
if (q != p) {
yTemp *= ((xTestArray[m] - xArray[q]) / (xArray[p] - xArray[q]));
}
}
yTestArray[m] += yTemp;
}
}
GraphicClass.drawFunc(xTestArray, yTestArray,
funcExpression + " interpolating result", "x", "y");
}
}
- 绘图工具类(GraphicClass.java)
package lagrange;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import javax.swing.*;
public class GraphicClass {
public static void drawFunc(double[] x, double[]y, String title, String xLabel, String yLabel) {
if (x.length != y.length) {
JOptionPane.showMessageDialog(null, "x length can not match y length");
return;
}
XYSeries series = new XYSeries("XYSeries");
for (int i = 0 ; i < x.length ; i++) {
series.add(x[i], y[i]);
}
XYSeriesCollection dataset = new XYSeriesCollection();
dataset.addSeries(series);
JFreeChart chart = ChartFactory.createXYLineChart(
title, // chart title
xLabel, // x axis label
yLabel, // y axis label
dataset, // data
PlotOrientation.VERTICAL,
false, // include legend
false, // tooltips
false // urls
);
ChartFrame frame = new ChartFrame("figure", chart);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Java实现结果
代码分析
- MATLAB的linspace函数是生成x1,x2之间的N点行线性的矢量,为闭区间。而Python中的列表生成式的range,以及Java中的Array,均是左闭右开区间。
- 测试结果均取k=3, n=10(MATLAB为10,Python/Java为11)时的结果,便于观察Runge现象。
- Java代码相对较繁琐,绘图工具jfreechart包的使用不如MATLAB/matplotlib方便,数组的生成也不如MATLAB/numpy快捷。
- 每种语言均需遵守各自的命名规范,良好的代码风格是必要的基础。Java命名风格建议参考AJCG(Alibaba Java Coding Guidelines)
这学期学计算方法,小白一枚,愿同君一起进步 ^_^