From 0c5e72eee56b6bb5996fa278d4966dd3a3458e88 Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 4 Jun 2013 00:55:49 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BF=D1=8F=D1=82=D0=B0=D1=8F=20=D0=BB=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=80=D0=B0=D1=82=D0=BE=D1=80=D0=BD=D0=B0=D1=8F=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Main.java | 2 +- src/com/nummethods/lr4/LR_4.java | 1 - src/com/nummethods/lr5/EulerMethod.java | 22 ++++ src/com/nummethods/lr5/Function.java | 9 ++ src/com/nummethods/lr5/Integral.java | 41 +++++++ src/com/nummethods/lr5/IntegrateMethod.java | 39 +++++++ src/com/nummethods/lr5/LR_5.java | 107 +++++++++++++++++++ src/com/nummethods/lr5/RungeKuttaMethod.java | 43 ++++++++ src/util/GraphicPanel.java | 4 +- 9 files changed, 264 insertions(+), 4 deletions(-) create mode 100644 src/com/nummethods/lr5/EulerMethod.java create mode 100644 src/com/nummethods/lr5/Function.java create mode 100644 src/com/nummethods/lr5/Integral.java create mode 100644 src/com/nummethods/lr5/IntegrateMethod.java create mode 100644 src/com/nummethods/lr5/LR_5.java create mode 100644 src/com/nummethods/lr5/RungeKuttaMethod.java diff --git a/src/Main.java b/src/Main.java index 4201daa..75c0aba 100644 --- a/src/Main.java +++ b/src/Main.java @@ -17,7 +17,7 @@ import javax.swing.border.EmptyBorder; */ public class Main extends JFrame { - private static final int NUM_OF_LABS = 4; + private static final int NUM_OF_LABS = 5; public static void main(String[] args) { try { diff --git a/src/com/nummethods/lr4/LR_4.java b/src/com/nummethods/lr4/LR_4.java index 22f83a3..b8fd0f2 100644 --- a/src/com/nummethods/lr4/LR_4.java +++ b/src/com/nummethods/lr4/LR_4.java @@ -2,7 +2,6 @@ package com.nummethods.lr4; import java.awt.Dimension; import javax.swing.JFrame; -import static javax.swing.JFrame.EXIT_ON_CLOSE; /** * v10 diff --git a/src/com/nummethods/lr5/EulerMethod.java b/src/com/nummethods/lr5/EulerMethod.java new file mode 100644 index 0000000..8752abc --- /dev/null +++ b/src/com/nummethods/lr5/EulerMethod.java @@ -0,0 +1,22 @@ +package com.nummethods.lr5; + +import java.awt.geom.Point2D; + +/** + * Метод Эйлера. + * @author aNNiMON + */ +public class EulerMethod extends IntegrateMethod { + + public EulerMethod(Integral integral) { + super(integral); + } + + @Override + protected double integrate(double xi, double h, double x0, double v0) { + double vi = (isEquals(xi, x0)) ? v0 : integrate(xi-h, h, x0, v0); + points.add(new Point2D.Double(xi, vi)); + return vi + h * integral.f(xi, vi); + } + +} diff --git a/src/com/nummethods/lr5/Function.java b/src/com/nummethods/lr5/Function.java new file mode 100644 index 0000000..31b6613 --- /dev/null +++ b/src/com/nummethods/lr5/Function.java @@ -0,0 +1,9 @@ +package com.nummethods.lr5; + +/** + * @author aNNiMON + */ +public interface Function { + + double f(double x, double v); +} diff --git a/src/com/nummethods/lr5/Integral.java b/src/com/nummethods/lr5/Integral.java new file mode 100644 index 0000000..c6e844e --- /dev/null +++ b/src/com/nummethods/lr5/Integral.java @@ -0,0 +1,41 @@ +package com.nummethods.lr5; + +/** + * @author aNNiMON + */ +public class Integral implements Function { + + private final Function func; + private final double v0, x0, xN; + private final int N; + + public Integral(Function func, double v0, double x0, double xN, int N) { + this.func = func; + this.v0 = v0; + this.x0 = x0; + this.xN = xN; + this.N = N; + } + + @Override + public double f(double x, double v) { + return func.f(x, v); + } + + public double getX0() { + return x0; + } + + public double getXN() { + return xN; + } + + public double getV0() { + return v0; + } + + public int getN() { + return N; + } + +} diff --git a/src/com/nummethods/lr5/IntegrateMethod.java b/src/com/nummethods/lr5/IntegrateMethod.java new file mode 100644 index 0000000..74a979d --- /dev/null +++ b/src/com/nummethods/lr5/IntegrateMethod.java @@ -0,0 +1,39 @@ +package com.nummethods.lr5; + +import java.awt.geom.Point2D; +import java.util.ArrayList; + +/** + * @author aNNiMON + */ +public abstract class IntegrateMethod { + + protected final Integral integral; + protected final ArrayList points; + + public IntegrateMethod(Integral integral) { + this.integral = integral; + this.points = new ArrayList(); + } + + public double calculate(int n) { + double h = (integral.getXN() - integral.getX0()) / n; + return integrate(integral.getXN(), h, integral.getX0(), integral.getV0()); + } + + protected abstract double integrate(double xi, double h, double x0, double v0); + + public Integral getIntegral() { + return integral; + } + + public Point2D[] getPoints() { + Point2D[] array = new Point2D[points.size()]; + array = points.toArray(array); + return array; + } + + protected boolean isEquals(double a, double b) { + return Math.abs(a - b) < 0.00001; + } +} diff --git a/src/com/nummethods/lr5/LR_5.java b/src/com/nummethods/lr5/LR_5.java new file mode 100644 index 0000000..fc89a8d --- /dev/null +++ b/src/com/nummethods/lr5/LR_5.java @@ -0,0 +1,107 @@ +package com.nummethods.lr5; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.geom.Point2D; +import javax.swing.JFrame; +import util.GraphicPanel; + +/** + * + * @author aNNiMON + */ +public class LR_5 extends JFrame { + + private static final Integral var2 = new Integral(new Function() { + + @Override + public double f(double x, double v) { + return Math.sin(x); + } + }, 0, -Math.PI, Math.PI, 50); // -0.006 | 4.386 + + private static final Integral var10 = new Integral(new Function() { + + @Override + public double f(double x, double v) { + return Math.log(x); + } + }, 0, 1, 5, 100); // 4.106 | 4.079 + + private static final Integral var12 = new Integral(new Function() { + + @Override + public double f(double x, double v) { + return 1 / (x); + } + }, 0, 1, 5, 75); + + public static void main(String[] args) { + new LR_5().setVisible(true); + } + + public LR_5() { + super("LR_5"); + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + + final Integral integral = var10; + + IntegrateMethod runge = new RungeKuttaMethod(integral); + System.out.println("Runge-Kutta: " + runge.calculate(integral.getN())); + final Point2D[] rungePoints = runge.getPoints(); + + IntegrateMethod euler = new EulerMethod(integral); + System.out.println("Euler: " + euler.calculate(integral.getN())); + final Point2D[] eulerPoints = euler.getPoints(); + + GraphicPanel panel = new GraphicPanel() { + + + private int xOld, yOld; + + @Override + protected void drawLabels(Graphics g, double x) { + g.setColor(Color.BLACK); + g.drawString("x: " + x, 10, 20); + g.setColor(Color.BLUE); + g.drawString("Runge-Kutta: " + findPoint(rungePoints, x), 10, 40); + g.setColor(new Color(0x00C000)); + g.drawString("Cubic Spline: " + findPoint(eulerPoints, x), 10, 60); + } + + @Override + protected void plot(Graphics g, double x, double y, boolean firstIteration) { + if (firstIteration) { + // Первая итерация - запоминаем координату + xOld = (int) x; + yOld = (int) y; + return; + } + g.fillRect(xOld - 1, yOld - 1, 3, 3); + g.drawLine(xOld, yOld, (int) x, (int) y); + xOld = (int) x; + yOld = (int) y; + } + }; + panel.addPoints(rungePoints); + panel.addPoints(eulerPoints); + + + panel.setPreferredSize(new Dimension(400, 300)); + add(panel); + + pack(); + setLocationRelativeTo(null); + } + + private double findPoint(Point2D[] array, double x) { + for (int i = 0; i < array.length; i++) { + double dx = Math.abs( array[i].getX() - x ); + if (dx < 0.001) { + return array[i].getY(); + } + } + return 0; + } +} diff --git a/src/com/nummethods/lr5/RungeKuttaMethod.java b/src/com/nummethods/lr5/RungeKuttaMethod.java new file mode 100644 index 0000000..972ab77 --- /dev/null +++ b/src/com/nummethods/lr5/RungeKuttaMethod.java @@ -0,0 +1,43 @@ +package com.nummethods.lr5; + +import java.awt.geom.Point2D; + +/** + * Метод Рунге-Кутты + * @author aNNiMON + */ +public class RungeKuttaMethod extends IntegrateMethod { + + public RungeKuttaMethod(Integral integral) { + super(integral); + } + + @Override + public double integrate(double xi, double h, double x0, double v0) { + double vi = isEquals(xi, x0) ? v0 : integrate(xi-h, h, x0, v0); + double k1 = k1(h, xi, vi); + double k2 = k2(h, xi, vi, k1); + double k3 = k3(h, xi, vi, k2); + double k4 = k4(h, xi, vi, k3); + + points.add(new Point2D.Double(xi, vi)); + return vi + (k1 + 2 * k2 + 2 * k3 + k4) / 6; + } + + private double k1(double h, double x, double v) { + return h * integral.f(x, v); + } + + private double k2(double h, double x, double v, double k1) { + return h * integral.f(x + h / 2, v + k1 / 2); + } + + private double k3(double h, double x, double v, double k2) { + return h * integral.f(x + h / 2, v + k2 / 2); + } + + private double k4(double h, double x, double v, double k3) { + return h * integral.f(x + h / 2, v + k3 / 2); + } + +} diff --git a/src/util/GraphicPanel.java b/src/util/GraphicPanel.java index 10d3691..ccf10de 100644 --- a/src/util/GraphicPanel.java +++ b/src/util/GraphicPanel.java @@ -81,7 +81,7 @@ public abstract class GraphicPanel extends JPanel { for (int i = 0; i < input.length; i++) { Point2D p = input[i]; - plot(g, (p.getX() - xMin) * dx, height - (p.getY() - yMin) * dy); + plot(g, (p.getX() - xMin) * dx, height - (p.getY() - yMin) * dy, i == 0); } } @@ -97,7 +97,7 @@ public abstract class GraphicPanel extends JPanel { protected abstract void drawLabels(Graphics g, double x); - protected void plot(Graphics g, double x, double y) { + protected void plot(Graphics g, double x, double y, boolean firstIteration) { g.drawLine((int) x, (int) y, (int) x, (int) y); }