Численное интегрирование методом Симпсона (реализация на Java)

Java   26 Февраль 2012  Автор статьи:  

Приведем пример реализации численного интегрирования методом Симпсона. На вход алгоритму подается набор точек, по которым требуется найти приближенное значение интеграла неизвестной функции. На выходе алгоритм выдает найденное приближенное значение. В данном методе интерполирование неизвестной функции осуществляется многочленом второй степени, т.е. на каждом отрезке функция приближается параболой.

Сложность алгоритма — O(n), где n — число точек, по которым осуществляется приближенное интегрирование. Все вычислительные операции производятся с типом данных double в целях повышения точности вычислений.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import java.io.PrintWriter;
import java.util.Scanner;

public class Solution {
    public static void main(String[] args) {
        // Для считывания воспользуемся классом Scanner
        // Для вывода - классом PrintWriter
        Scanner scanner = new Scanner(System.in);
        PrintWriter printWriter = new PrintWriter(System.out);

        // Объявляем и считываем число точек,
        // по которым будем вычислять приближенное
        // значение интеграла функции
        int pointsCount = scanner.nextInt();

        // Точки будем хранить в массиве структур;
        // его размер, очевидно, равен pointsCount
        Point[] points = new Point[pointsCount];

        // Считываем абсциссы и ординаты точек
        for (int i = 0; i < pointsCount; i++) {
            double x = scanner.nextDouble();
            double y = scanner.nextDouble();

            points[i] = new Point(x, y);
        }

        // Изначально приравниваем приближенное
        // значение интеграла к нулю
        double integralValue = 0.0;

        // Для троек соседних точек считаем
        // площадь под графиком параболы,
        // которую они образуют, по
        // соответствующим теоретическим формулам;
        // заметим, что в этом случае указатель i
        // на каждой итерации сдвигается на 2 ед.
        for (int i = 2; i < pointsCount; i += 2) {
            double h = points[i].getX() - points[i - 2].getX();
            integralValue += h * (points[i - 2].getY() + 4 * points[i - 1].getY() + points[i].getY());
        }

        // Для небольшого ускорения работы алгоритма
        // деление на 6 выносят за пределы цикла
        integralValue /= 6.0;

        // Выводим приближенное значение интеграла
        printWriter.println(integralValue);

        // После выполнения программы необходимо закрыть
        // потоки ввода и вывода
        scanner.close();
        printWriter.close();
    }

    // Для удобства хранения задаваемых точек
    // создадим простой класс, хранящий абсциссу
    // и ординату точки соответственно
    private static final class Point {
        private final double x;
        private final double y;

        private Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        public double getX() {
            return x;
        }

        public double getY() {
            return y;
        }
    }
}

Научиться программировать

  • на Delphi

  • на Java

  • на C++