diff --git a/sem5/math-calculations/lab3/.idea/compiler.xml b/sem5/math-calculations/lab3/.idea/compiler.xml
new file mode 100644
index 00000000..5e793c4d
--- /dev/null
+++ b/sem5/math-calculations/lab3/.idea/compiler.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sem5/math-calculations/lab3/.idea/encodings.xml b/sem5/math-calculations/lab3/.idea/encodings.xml
new file mode 100644
index 00000000..15a15b21
--- /dev/null
+++ b/sem5/math-calculations/lab3/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/sem5/math-calculations/lab3/.idea/google-java-format.xml b/sem5/math-calculations/lab3/.idea/google-java-format.xml
new file mode 100644
index 00000000..2aa056da
--- /dev/null
+++ b/sem5/math-calculations/lab3/.idea/google-java-format.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sem5/math-calculations/lab3/.idea/misc.xml b/sem5/math-calculations/lab3/.idea/misc.xml
new file mode 100644
index 00000000..b2783ca6
--- /dev/null
+++ b/sem5/math-calculations/lab3/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sem5/math-calculations/lab3/.idea/uiDesigner.xml b/sem5/math-calculations/lab3/.idea/uiDesigner.xml
new file mode 100644
index 00000000..e96534fb
--- /dev/null
+++ b/sem5/math-calculations/lab3/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/sem5/math-calculations/lab3/.idea/workspace.xml b/sem5/math-calculations/lab3/.idea/workspace.xml
new file mode 100644
index 00000000..c284cf8b
--- /dev/null
+++ b/sem5/math-calculations/lab3/.idea/workspace.xml
@@ -0,0 +1,701 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1600503882605
+
+
+ 1600503882605
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ file://$PROJECT_DIR$/src/main/java/group343/stepyrev/lab2_2/NewtonPolynomial.java
+ 171
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ javafx11
+
+
+
+
+
+
+
+
+
+
+
+ 11
+
+
+
+
+
+
+
+
+
+
+
+ 11 (3)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sem5/math-calculations/lab3/pom.xml b/sem5/math-calculations/lab3/pom.xml
new file mode 100644
index 00000000..733f4052
--- /dev/null
+++ b/sem5/math-calculations/lab3/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+ secondLaboratory
+ secondLaboratory
+ 1.0-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 8
+
+
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.3.2
+ test
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+
+
\ No newline at end of file
diff --git a/sem5/math-calculations/lab3/secondLaboratory.iml b/sem5/math-calculations/lab3/secondLaboratory.iml
new file mode 100644
index 00000000..78b2cc53
--- /dev/null
+++ b/sem5/math-calculations/lab3/secondLaboratory.iml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab/FunctionPoint.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab/FunctionPoint.java
new file mode 100644
index 00000000..b5d9fc98
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab/FunctionPoint.java
@@ -0,0 +1,28 @@
+package group343.stepyrev.lab;
+
+public class FunctionPoint {
+ private final Double value;
+ private final Double functionValue;
+ private Double distanceToPoint;
+
+ public FunctionPoint(Double value, Double functionValue) {
+ this.value = value;
+ this.functionValue = functionValue;
+ }
+
+ public void setDistanceToPoint(Double point) {
+ distanceToPoint = Math.abs(point - value);
+ }
+
+ public Double getDistanceToPoint() {
+ return distanceToPoint;
+ }
+
+ public Double getValue() {
+ return value;
+ }
+
+ public Double getFunctionValue() {
+ return functionValue;
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab/LagrangePolynomial.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab/LagrangePolynomial.java
new file mode 100644
index 00000000..c95c81f5
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab/LagrangePolynomial.java
@@ -0,0 +1,106 @@
+package group343.stepyrev.lab;
+
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+
+/** Класс, который реализует интерполяционный многочлен. */
+public class LagrangePolynomial {
+ private final Integer M;
+ private final Double A;
+ private final Double B;
+
+ private Double X;
+ private Integer N;
+
+ private List functionPoints;
+ private List sortedPoints;
+
+ public LagrangePolynomial(Integer m, Double a, Double b) {
+ M = m;
+ A = a;
+ B = b;
+
+ functionPoints = initializeFunctionPoints();
+ }
+
+ public List getFunctionPoints() {
+ return functionPoints;
+ }
+
+ /**
+ * Метод, который заполняет таблицу значений.
+ * @return - таблицу значений
+ */
+ private List initializeFunctionPoints() {
+ List result = new LinkedList<>();
+
+ for (int j = 0; j <= M; j++) {
+ Double point = A + j * (B - A) / M;
+ Double funcValue = getFunctionValue(point);
+ result.add(new FunctionPoint(point, funcValue));
+ }
+
+ return result;
+ }
+
+ public List sortFunctionPoints(Double x, Integer n) {
+ X = x;
+ N = n;
+ sortedPoints = functionPoints;
+ for (FunctionPoint point : sortedPoints) {
+ point.setDistanceToPoint(x);
+ }
+
+ Comparator comparator = Comparator.comparing(FunctionPoint::getDistanceToPoint);
+ sortedPoints.sort(comparator);
+ sortedPoints = sortedPoints.subList(0, N + 1);
+
+ return sortedPoints;
+ }
+
+ public Double getPolynomialValue() {
+ Double result = 0D;
+
+ double numerator;
+ double denominator;
+ double curPoint;
+ double curPointValue;
+ for (int k = 0; k < sortedPoints.size(); k++) {
+ curPoint = sortedPoints.get(k).getValue();
+ curPointValue = sortedPoints.get(k).getFunctionValue();
+
+ numerator = countPointComposition(k, X);
+ denominator = countPointComposition(k, curPoint);
+ result += curPointValue * numerator / denominator;
+ }
+
+ return result;
+ }
+
+ private Double countPointComposition(int k, double curPoint) {
+ double result = 1d;
+ double xI;
+
+ for (int i = 0; i < functionPoints.size(); i++) {
+ if (i == k) {
+ continue;
+ }
+
+ xI = functionPoints.get(i).getValue();
+ result *= (curPoint - xI);
+ }
+
+ return result;
+ }
+
+
+ /**
+ * Метод, который возвращает значение исходной функции в точке.
+ * @param point - точка, в которой требуется найти значени
+ * @return - значение функции в точке
+ */
+ public double getFunctionValue(double point) {
+ return Math.exp(-point) - Math.pow(point, 2) / 2; // exp(-x) - x^2 / 2
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab/Main.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab/Main.java
new file mode 100644
index 00000000..9cdfa0d1
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab/Main.java
@@ -0,0 +1,183 @@
+package group343.stepyrev.lab;
+
+import group343.stepyrev.lab2.NewtonPolynomial;
+import group343.stepyrev.util.PrettyPrinter;
+import java.util.List;
+import java.util.Scanner;
+
+public class Main {
+
+ private static double A;
+ private static double B;
+ private static Integer M;
+ private static Integer N;
+ private static Double X;
+
+ private static Scanner scanner;
+ private static NewtonPolynomial polynomial;
+
+ private final static PrettyPrinter printer = new PrettyPrinter(System.out);
+
+ public static void main(String[] args) {
+ scanner = new Scanner(System.in);
+ printIntroduction();
+
+ readInitialParams();
+ printInitialParams();
+ polynomial = new NewtonPolynomial(M, A, B);
+
+ List funcTable = polynomial.getFunctionPoints();
+ System.out.println("Таблица значений: ");
+ printFuncTable(funcTable);
+
+ String answer = "yes";
+ while (answer.equals("yes")) {
+ doPolynomialCalculations();
+
+ System.out.println("Если хотите продолжить вычисления с новыми значениями x и n, введите yes.");
+ answer = scanner.nextLine();
+ }
+ }
+
+ private static void doPolynomialCalculations() {
+ System.out.println("Введите точку интерполирования x: ");
+ X = readDouble();
+ readInterpolationPolDegree();
+
+ System.out.println(String
+ .format("Первые %d значений таблицы после сортировки относительно удаления от x (%.5f): ", N + 1, X));
+ List funcTable = polynomial.sortFunctionPoints(X, N);
+ printFuncTable(funcTable);
+
+ Double polValue = polynomial.getPolynomialValue();
+ System.out.println(
+ String.format("Значение интерполяционного многочлена в точке %.5f: %.14f", X, polValue));
+
+ Double absoluteValue = polynomial.getFunctionValue(X);
+ Double difference = Math.abs(absoluteValue - polValue);
+ System.out.println(String.format("Значение абсолютной фактической погрешности: %.14f", difference));
+ }
+
+ /**
+ * Метод, в котором считываются исходные параметры задачи.
+ */
+ private static void readInitialParams() {
+ System.out.println("Введите число значений в таблице: ");
+ M = readInt() - 1;
+ while (M <= 0) {
+ System.out.println("Введите M >= 2.");
+ M = readInt() - 1;
+ }
+
+ System.out.println("Введите левый конец отрезка: ");
+ A = readDouble();
+
+ System.out.println("Введите правый конец отрезка: ");
+ B = readDouble();
+ }
+
+ /**
+ * Метод, который считывает степень интерполяционного многочлена.
+ */
+ private static void readInterpolationPolDegree() {
+ System.out
+ .println(String.format("Введите степень интерполяционного многочлена N (N <= %d): ", M));
+ N = readInt();
+ while (N > M || N <= 0) {
+ System.out.println(String.format("Введите целое значение N: N >= 1, N <= %d: ", M));
+ N = readInt();
+ }
+ }
+
+ private static Double readDouble() {
+ String readValue = scanner.nextLine();
+ while (!isDoubleValue(readValue)) {
+ System.out.println("Пожалуйста, введите корректное значение (дробное или целое число).");
+ readValue = scanner.nextLine();
+ }
+
+ return Double.parseDouble(readValue);
+ }
+
+ /**
+ * Метод, который считывает из консоли число.
+ *
+ * @return - возвращает целое число
+ */
+ private static Integer readInt() {
+ String readValue = scanner.nextLine();
+ while (!isIntValue(readValue)) {
+ System.out.println("Пожалуйста, введите целое значение.");
+ readValue = scanner.nextLine();
+ }
+
+ return Integer.parseInt(readValue);
+ }
+
+ /**
+ * Метод, которые проверяет, является ли целым числом строка.
+ *
+ * @param value - исходная строка
+ * @return - true, если является целым числом, иначе false
+ */
+ private static boolean isIntValue(String value) {
+ try {
+ Integer.parseInt(value);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean isDoubleValue(String value) {
+ try {
+ Double.parseDouble(value);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * Метод, который печатает таблицу значений.
+ */
+ private static void printFuncTable(List table) {
+ String[][] convertedTable = new String[table.size() + 1][2];
+ convertedTable[0][0] = "xK";
+ convertedTable[0][1] = "f(xK)";
+
+ for (int i = 0; i < table.size(); i++) {
+ Double key = table.get(i).getValue();
+ Double value = table.get(i).getFunctionValue();
+ convertedTable[i + 1][0] = String.valueOf(key);
+ convertedTable[i + 1][1] = String.valueOf(value);
+
+ //System.out.println(String.format("x%d: %.2f, f(x%d): %.2f", i, key, i, value));
+ }
+
+ printer.print(convertedTable);
+ System.out.println(" ");
+ }
+
+ /**
+ * Метод, который печатает исходные параметры задачи.
+ */
+ private static void printInitialParams() {
+ System.out.println("");
+ System.out.println(String.format("Число значение в таблице: %d", M + 1));
+ System.out.println(String.format("Исходный промежуток: [%.2f; %.2f]", A, B));
+ }
+
+ /**
+ * Метод, который печатает описание лабораторной работы.
+ */
+ private static void printIntroduction() {
+ System.out.println("Лабораторная работа номер 2");
+ System.out.println("На тему: \"Численные методы решения нелинейных уравнений\".");
+ System.out.println("Работа выполнена студентом 343 группы СПбГУ Степыревом Даниилом");
+ System.out.println("Вариант 12.");
+ System.out.println("Функция, приближенное значение которой будет вычисляться: "
+ + "exp(-x) - x^2 / 2.");
+ System.out.println("\n");
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2/Main.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2/Main.java
new file mode 100644
index 00000000..b170cf58
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2/Main.java
@@ -0,0 +1,171 @@
+package group343.stepyrev.lab2;
+
+import group343.stepyrev.lab.FunctionPoint;
+import group343.stepyrev.lab.LagrangePolynomial;
+import java.util.List;
+import java.util.Scanner;
+
+public class Main {
+
+ private static double A;
+ private static double B;
+ private static Integer M;
+ private static Integer N;
+ private static Double X;
+
+ private static Scanner scanner;
+ private static LagrangePolynomial polynomial;
+
+ public static void main(String[] args) {
+ scanner = new Scanner(System.in);
+ printIntroduction();
+
+ readInitialParams();
+ printInitialParams();
+ polynomial = new LagrangePolynomial(M, A, B);
+
+ List funcTable = polynomial.getFunctionPoints();
+ System.out.println("Таблица значений: ");
+ printFuncTable(funcTable);
+
+ String answer = "yes";
+ while (answer.equals("yes")) {
+ doPolynomialCalculations();
+
+ System.out.println("Если хотите продолжить вычисления с новыми значениями x и n, введите yes.");
+ answer = scanner.nextLine();
+ }
+ }
+
+ private static void doPolynomialCalculations() {
+ System.out.println("Введите точку интерполирования x: ");
+ X = readDouble();
+ readInterpolationPolDegree();
+
+ System.out.println(String
+ .format("Первые %d значений таблицы после сортировки относительно удаления от x (%.5f): ", N + 1, X));
+ List funcTable = polynomial.sortFunctionPoints(X, N);
+ printFuncTable(funcTable);
+
+ Double polValue = polynomial.getPolynomialValue();
+ System.out.println(
+ String.format("Значение интерполяционного многочлена в точке %.5f: %.14f", X, polValue));
+
+ Double absoluteValue = polynomial.getFunctionValue(X);
+ Double difference = Math.abs(absoluteValue - polValue);
+ System.out.println(String.format("Значение абсолютной фактической погрешности: %.14f", difference));
+ }
+
+ /**
+ * Метод, в котором считываются исходные параметры задачи.
+ */
+ private static void readInitialParams() {
+ System.out.println("Введите число значений в таблице: ");
+ M = readInt() - 1;
+ while (M <= 0) {
+ System.out.println("Введите M >= 2.");
+ M = readInt() - 1;
+ }
+
+ System.out.println("Введите левый конец отрезка: ");
+ A = readDouble();
+
+ System.out.println("Введите правый конец отрезка: ");
+ B = readDouble();
+ }
+
+ /**
+ * Метод, который считывает степень интерполяционного многочлена.
+ */
+ private static void readInterpolationPolDegree() {
+ System.out
+ .println(String.format("Введите степень интерполяционного многочлена N (N <= %d): ", M));
+ N = readInt();
+ while (N > M || N <= 0) {
+ System.out.println(String.format("Введите целое значение N: N >= 1, N <= %d: ", M));
+ N = readInt();
+ }
+ }
+
+ private static Double readDouble() {
+ String readValue = scanner.nextLine();
+ while (!isDoubleValue(readValue)) {
+ System.out.println("Пожалуйста, введите корректное значение (дробное или целое число).");
+ readValue = scanner.nextLine();
+ }
+
+ return Double.parseDouble(readValue);
+ }
+
+ /**
+ * Метод, который считывает из консоли число.
+ *
+ * @return - возвращает целое число
+ */
+ private static Integer readInt() {
+ String readValue = scanner.nextLine();
+ while (!isIntValue(readValue)) {
+ System.out.println("Пожалуйста, введите целое значение.");
+ readValue = scanner.nextLine();
+ }
+
+ return Integer.parseInt(readValue);
+ }
+
+ /**
+ * Метод, которые проверяет, является ли целым числом строка.
+ *
+ * @param value - исходная строка
+ * @return - true, если является целым числом, иначе false
+ */
+ private static boolean isIntValue(String value) {
+ try {
+ Integer.parseInt(value);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean isDoubleValue(String value) {
+ try {
+ Double.parseDouble(value);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * Метод, который печатает таблицу значений.
+ */
+ private static void printFuncTable(List table) {
+ for (int i = 0; i < table.size(); i++) {
+ Double key = table.get(i).getValue();
+ Double value = table.get(i).getFunctionValue();
+ System.out.println(String.format("x%d: %.2f, f(x%d): %.2f", i, key, i, value));
+ }
+ }
+
+ /**
+ * Метод, который печатает исходные параметры задачи.
+ */
+ private static void printInitialParams() {
+ System.out.println("");
+ System.out.println(String.format("Число значение в таблице: %d", M + 1));
+ System.out.println(String.format("Исходный промежуток: [%.2f; %.2f]", A, B));
+ }
+
+ /**
+ * Метод, который печатает описание лабораторной работы.
+ */
+ private static void printIntroduction() {
+ System.out.println("Лабораторная работа номер 2");
+ System.out.println("На тему: \"Численные методы решения нелинейных уравнений\".");
+ System.out.println("Работа выполнена студентом 343 группы СПбГУ Степыревом Даниилом");
+ System.out.println("Вариант 12.");
+ System.out.println("Функция, приближенное значение которой будет вычисляться: "
+ + "exp(-x) - x^2 / 2.");
+ System.out.println("\n");
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2/NewtonCoef.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2/NewtonCoef.java
new file mode 100644
index 00000000..69c41fea
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2/NewtonCoef.java
@@ -0,0 +1,19 @@
+package group343.stepyrev.lab2;
+
+public class NewtonCoef {
+ private final Integer number;
+ private final Double value;
+
+ public NewtonCoef(Integer number, Double value) {
+ this.number = number;
+ this.value = value;
+ }
+
+ public Double getValue() {
+ return value;
+ }
+
+ public Integer getNumber() {
+ return number;
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2/NewtonPolynomial.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2/NewtonPolynomial.java
new file mode 100644
index 00000000..a075fea7
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2/NewtonPolynomial.java
@@ -0,0 +1,169 @@
+package group343.stepyrev.lab2;
+
+import group343.stepyrev.lab.FunctionPoint;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Класс, который реализует интерполяионный многочлен Ньютона.
+ */
+public class NewtonPolynomial {
+
+ private final Integer M;
+ private final Double A;
+ private final Double B;
+
+ private Double X;
+ private Integer N;
+
+ private List functionPoints;
+ private List sortedPoints;
+ private Map> newtonCoefficients;
+
+ public NewtonPolynomial(Integer m, Double a, Double b) {
+ M = m;
+ A = a;
+ B = b;
+
+ functionPoints = initializeFunctionPoints();
+ newtonCoefficients = new HashMap<>();
+ }
+
+ public List getFunctionPoints() {
+ return functionPoints;
+ }
+
+ /**
+ * Метод, который заполняет таблицу значений.
+ *
+ * @return - таблицу значений
+ */
+ private List initializeFunctionPoints() {
+ List result = new LinkedList<>();
+
+ for (int j = 0; j <= M; j++) {
+ Double point = A + j * (B - A) / M;
+ Double funcValue = getFunctionValue(point);
+ result.add(new FunctionPoint(point, funcValue));
+ }
+
+ return result;
+ }
+
+ public List sortFunctionPoints(Double x, Integer n) {
+ X = x;
+ N = n;
+ sortedPoints = functionPoints;
+ for (FunctionPoint point : sortedPoints) {
+ point.setDistanceToPoint(x);
+ }
+
+ Comparator comparator = Comparator.comparing(FunctionPoint::getDistanceToPoint);
+ sortedPoints.sort(comparator);
+ sortedPoints = sortedPoints.subList(0, N + 1);
+ findNewtonCoefficients();
+
+ return sortedPoints;
+ }
+
+ private void findNewtonCoefficients() {
+ List coefficients = new LinkedList<>();
+ newtonCoefficients
+ .put(0,
+ Collections.singletonList(new NewtonCoef(0, sortedPoints.get(0).getFunctionValue())));
+
+ for (int degree = 1; degree < N + 1; degree++) {
+ for (int i = 0; i + degree < N + 1; i++) {
+ double elemValue = countNewtonCoefficient(i, i + degree);
+ coefficients.add(new NewtonCoef(i,
+ elemValue)); // первая координата точки - номер первого элемента, вторая - значения коэффициента
+ }
+ newtonCoefficients.put(degree, coefficients);
+
+ coefficients = new LinkedList<>();
+ }
+ }
+
+ private double countNewtonCoefficient(int fstNumber, int lastNumber) {
+ int degree = lastNumber - fstNumber;
+ double fstElem;
+ double sndElem;
+ double denominator;
+
+ if (degree == 1) {
+ fstElem = sortedPoints.get(lastNumber).getFunctionValue();
+ sndElem = sortedPoints.get(fstNumber).getFunctionValue();
+ denominator =
+ sortedPoints.get(lastNumber).getValue() - sortedPoints.get(fstNumber).getValue();
+ } else {
+ List thisDegreeCoefs = newtonCoefficients.get(degree - 1);
+
+ fstElem = getFunctionPointValue(thisDegreeCoefs, fstNumber + 1);
+ sndElem = getFunctionPointValue(thisDegreeCoefs, fstNumber);
+ denominator = sortedPoints.get(lastNumber).getValue() - sortedPoints.get(fstNumber).getValue();
+ }
+
+ return (fstElem - sndElem) / denominator;
+ }
+
+ private double getFunctionPointValue(List points, int index) {
+ for (NewtonCoef point : points) {
+ if (point.getNumber() == index) { // FIXME
+ return point.getValue();
+ }
+ }
+
+ return 0;
+ }
+
+ public Double getPolynomialValue() {
+ double result = 0D;
+
+ double aK;
+ double xComposition;
+ for (int k = 0; k < sortedPoints.size(); k++) {
+ aK = getNewtonCoefficient(k);
+ xComposition = getXComposition(k);
+ result += aK * xComposition;
+ }
+
+ return result;
+ }
+
+ /**
+ * Метод, который вычисляет произведение иксов: (x - x0)(x - x1) ... (x - x(K-1))
+ *
+ * @param k - номер последнего x
+ * @return - произведение иксов
+ */
+ private double getXComposition(int k) {
+ double result = 1;
+ double xK;
+ for (int i = 0; i < k; i++) {
+ xK = sortedPoints.get(i).getValue();
+ result *= (X - xK);
+ }
+
+ return result;
+ }
+
+ private double getNewtonCoefficient(int k) {
+ return newtonCoefficients.get(k).get(0).getValue();
+ }
+
+ /**
+ * Метод, который возвращает значение исходной функции в точке.
+ *
+ * @param point - точка, в которой требуется найти значени
+ * @return - значение функции в точке
+ */
+ public double getFunctionValue(double point) {
+ return Math.exp(-point) - Math.pow(point, 2) / 2; // exp(-x) - x^2 / 2
+ }
+
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_1/FunctionPoint.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_1/FunctionPoint.java
new file mode 100644
index 00000000..568fc4b5
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_1/FunctionPoint.java
@@ -0,0 +1,28 @@
+package group343.stepyrev.lab2_1;
+
+public class FunctionPoint {
+ private final Double value;
+ private final Double functionValue;
+ private Double distanceToPoint;
+
+ public FunctionPoint(Double value, Double functionValue) {
+ this.value = value;
+ this.functionValue = functionValue;
+ }
+
+ public void setDistanceToPoint(Double point) {
+ distanceToPoint = Math.abs(point - value);
+ }
+
+ public Double getDistanceToPoint() {
+ return distanceToPoint;
+ }
+
+ public Double getValue() {
+ return value;
+ }
+
+ public Double getFunctionValue() {
+ return functionValue;
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_1/LagrangePolynomial.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_1/LagrangePolynomial.java
new file mode 100644
index 00000000..ac948bc1
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_1/LagrangePolynomial.java
@@ -0,0 +1,106 @@
+package group343.stepyrev.lab2_1;
+
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+
+/** Класс, который реализует интерполяционный многочлен. */
+public class LagrangePolynomial {
+ private final Integer M;
+ private final Double A;
+ private final Double B;
+
+ private Double X;
+ private Integer N;
+
+ private List functionPoints;
+ private List sortedPoints;
+
+ public LagrangePolynomial(Integer m, Double a, Double b) {
+ M = m;
+ A = a;
+ B = b;
+
+ functionPoints = initializeFunctionPoints();
+ }
+
+ public List getFunctionPoints() {
+ return functionPoints;
+ }
+
+ /**
+ * Метод, который заполняет таблицу значений.
+ * @return - таблицу значений
+ */
+ private List initializeFunctionPoints() {
+ List result = new LinkedList<>();
+
+ for (int j = 0; j <= M; j++) {
+ Double point = A + j * (B - A) / M;
+ Double funcValue = getFunctionValue(point);
+ result.add(new FunctionPoint(point, funcValue));
+ }
+
+ return result;
+ }
+
+ public List sortFunctionPoints(Double x, Integer n) {
+ X = x;
+ N = n;
+ sortedPoints = functionPoints;
+ for (FunctionPoint point : sortedPoints) {
+ point.setDistanceToPoint(x);
+ }
+
+ Comparator comparator = Comparator.comparing(FunctionPoint::getDistanceToPoint);
+ sortedPoints.sort(comparator);
+ sortedPoints = sortedPoints.subList(0, N + 1);
+
+ return sortedPoints;
+ }
+
+ public Double getPolynomialValue() {
+ Double result = 0D;
+
+ double numerator;
+ double denominator;
+ double curPoint;
+ double curPointValue;
+ for (int k = 0; k < sortedPoints.size(); k++) {
+ curPoint = sortedPoints.get(k).getValue();
+ curPointValue = sortedPoints.get(k).getFunctionValue();
+
+ numerator = countPointComposition(k, X);
+ denominator = countPointComposition(k, curPoint);
+ result += curPointValue * numerator / denominator;
+ }
+
+ return result;
+ }
+
+ private Double countPointComposition(int k, double curPoint) {
+ double result = 1d;
+ double xI;
+
+ for (int i = 0; i < functionPoints.size(); i++) {
+ if (i == k) {
+ continue;
+ }
+
+ xI = functionPoints.get(i).getValue();
+ result *= (curPoint - xI);
+ }
+
+ return result;
+ }
+
+
+ /**
+ * Метод, который возвращает значение исходной функции в точке.
+ * @param point - точка, в которой требуется найти значени
+ * @return - значение функции в точке
+ */
+ public double getFunctionValue(double point) {
+ return Math.exp(-point) - Math.pow(point, 2) / 2; // exp(-x) - x^2 / 2
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_1/Main.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_1/Main.java
new file mode 100644
index 00000000..833fdc12
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_1/Main.java
@@ -0,0 +1,184 @@
+package group343.stepyrev.lab2_1;
+
+import group343.stepyrev.lab2_1.FunctionPoint;
+import group343.stepyrev.lab2_1.LagrangePolynomial;
+import group343.stepyrev.util.PrettyPrinter;
+import java.util.List;
+import java.util.Scanner;
+
+public class Main {
+
+ private static double A;
+ private static double B;
+ private static Integer M;
+ private static Integer N;
+ private static Double X;
+
+ private static Scanner scanner;
+ private static LagrangePolynomial polynomial;
+
+ private final static PrettyPrinter printer = new PrettyPrinter(System.out);
+
+ public static void main(String[] args) {
+ scanner = new Scanner(System.in);
+ printIntroduction();
+
+ readInitialParams();
+ printInitialParams();
+ polynomial = new LagrangePolynomial(M, A, B);
+
+ List funcTable = polynomial.getFunctionPoints();
+ System.out.println("Таблица значений: ");
+ printFuncTable(funcTable);
+
+ String answer = "yes";
+ while (answer.equals("yes")) {
+ doPolynomialCalculations();
+
+ System.out.println("Если хотите продолжить вычисления с новыми значениями x и n, введите yes.");
+ answer = scanner.nextLine();
+ }
+ }
+
+ private static void doPolynomialCalculations() {
+ System.out.println("Введите точку интерполирования x: ");
+ X = readDouble();
+ readInterpolationPolDegree();
+
+ System.out.println(String
+ .format("Первые %d значений таблицы после сортировки относительно удаления от x (%.5f): ", N + 1, X));
+ List funcTable = polynomial.sortFunctionPoints(X, N);
+ printFuncTable(funcTable);
+
+ Double polValue = polynomial.getPolynomialValue();
+ System.out.println(
+ String.format("Значение интерполяционного многочлена в точке %.5f: %.14f", X, polValue));
+
+ Double absoluteValue = polynomial.getFunctionValue(X);
+ Double difference = Math.abs(absoluteValue - polValue);
+ System.out.println(String.format("Значение абсолютной фактической погрешности: %.14f", difference));
+ }
+
+ /**
+ * Метод, в котором считываются исходные параметры задачи.
+ */
+ private static void readInitialParams() {
+ System.out.println("Введите число значений в таблице: ");
+ M = readInt() - 1;
+ while (M <= 0) {
+ System.out.println("Введите M >= 2.");
+ M = readInt() - 1;
+ }
+
+ System.out.println("Введите левый конец отрезка: ");
+ A = readDouble();
+
+ System.out.println("Введите правый конец отрезка: ");
+ B = readDouble();
+ }
+
+ /**
+ * Метод, который считывает степень интерполяционного многочлена.
+ */
+ private static void readInterpolationPolDegree() {
+ System.out
+ .println(String.format("Введите степень интерполяционного многочлена N (N <= %d): ", M));
+ N = readInt();
+ while (N > M || N <= 0) {
+ System.out.println(String.format("Введите целое значение N: N >= 1, N <= %d: ", M));
+ N = readInt();
+ }
+ }
+
+ private static Double readDouble() {
+ String readValue = scanner.nextLine();
+ while (!isDoubleValue(readValue)) {
+ System.out.println("Пожалуйста, введите корректное значение (дробное или целое число).");
+ readValue = scanner.nextLine();
+ }
+
+ return Double.parseDouble(readValue);
+ }
+
+ /**
+ * Метод, который считывает из консоли число.
+ *
+ * @return - возвращает целое число
+ */
+ private static Integer readInt() {
+ String readValue = scanner.nextLine();
+ while (!isIntValue(readValue)) {
+ System.out.println("Пожалуйста, введите целое значение.");
+ readValue = scanner.nextLine();
+ }
+
+ return Integer.parseInt(readValue);
+ }
+
+ /**
+ * Метод, которые проверяет, является ли целым числом строка.
+ *
+ * @param value - исходная строка
+ * @return - true, если является целым числом, иначе false
+ */
+ private static boolean isIntValue(String value) {
+ try {
+ Integer.parseInt(value);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean isDoubleValue(String value) {
+ try {
+ Double.parseDouble(value);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * Метод, который печатает таблицу значений.
+ */
+ private static void printFuncTable(List table) {
+ String[][] convertedTable = new String[table.size() + 1][2];
+ convertedTable[0][0] = "xK";
+ convertedTable[0][1] = "f(xK)";
+
+ for (int i = 0; i < table.size(); i++) {
+ Double key = table.get(i).getValue();
+ Double value = table.get(i).getFunctionValue();
+ convertedTable[i + 1][0] = String.valueOf(key);
+ convertedTable[i + 1][1] = String.valueOf(value);
+
+ //System.out.println(String.format("x%d: %.2f, f(x%d): %.2f", i, key, i, value));
+ }
+
+ printer.print(convertedTable);
+ System.out.println(" ");
+ }
+
+ /**
+ * Метод, который печатает исходные параметры задачи.
+ */
+ private static void printInitialParams() {
+ System.out.println("");
+ System.out.println(String.format("Число значение в таблице: %d", M + 1));
+ System.out.println(String.format("Исходный промежуток: [%.2f; %.2f]", A, B));
+ }
+
+ /**
+ * Метод, который печатает описание лабораторной работы.
+ */
+ private static void printIntroduction() {
+ System.out.println("Лабораторная работа номер 2");
+ System.out.println("На тему: \"Численные методы решения нелинейных уравнений\".");
+ System.out.println("Работа выполнена студентом 343 группы СПбГУ Степыревом Даниилом");
+ System.out.println("Вариант 12.");
+ System.out.println("Функция, приближенное значение которой будет вычисляться: "
+ + "exp(-x) - x^2 / 2.");
+ System.out.println("\n");
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_2/Main.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_2/Main.java
new file mode 100644
index 00000000..3911f49f
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_2/Main.java
@@ -0,0 +1,183 @@
+package group343.stepyrev.lab2_2;
+
+import group343.stepyrev.lab2_1.FunctionPoint;
+import group343.stepyrev.util.PrettyPrinter;
+import java.util.List;
+import java.util.Scanner;
+
+public class Main {
+
+ private static double A;
+ private static double B;
+ private static Integer M;
+ private static Integer N;
+ private static Double X;
+
+ private static Scanner scanner;
+ private static NewtonPolynomial polynomial;
+
+ private final static PrettyPrinter printer = new PrettyPrinter(System.out);
+
+ public static void main(String[] args) {
+ scanner = new Scanner(System.in);
+ printIntroduction();
+
+ readInitialParams();
+ printInitialParams();
+ polynomial = new NewtonPolynomial(M, A, B);
+
+ List funcTable = polynomial.getFunctionPoints();
+ System.out.println("Таблица значений: ");
+ printFuncTable(funcTable);
+
+ String answer = "yes";
+ while (answer.equals("yes")) {
+ doPolynomialCalculations();
+
+ System.out.println("Если хотите продолжить вычисления с новыми значениями x и n, введите yes.");
+ answer = scanner.nextLine();
+ }
+ }
+
+ private static void doPolynomialCalculations() {
+ System.out.println("Введите точку интерполирования x: ");
+ X = readDouble();
+ readInterpolationPolDegree();
+
+ System.out.println(String
+ .format("Первые %d значений таблицы после сортировки относительно удаления от x (%.5f): ", N + 1, X));
+ List funcTable = polynomial.sortFunctionPoints(X, N);
+ printFuncTable(funcTable);
+
+ Double polValue = polynomial.getPolynomialValue();
+ System.out.println(
+ String.format("Значение интерполяционного многочлена в точке %.5f: %.14f", X, polValue));
+
+ Double absoluteValue = polynomial.getFunctionValue(X);
+ Double difference = Math.abs(absoluteValue - polValue);
+ System.out.println(String.format("Значение абсолютной фактической погрешности: %.14f", difference));
+ }
+
+ /**
+ * Метод, в котором считываются исходные параметры задачи.
+ */
+ private static void readInitialParams() {
+ System.out.println("Введите число значений в таблице: ");
+ M = readInt() - 1;
+ while (M <= 0) {
+ System.out.println("Введите M >= 2.");
+ M = readInt() - 1;
+ }
+
+ System.out.println("Введите левый конец отрезка: ");
+ A = readDouble();
+
+ System.out.println("Введите правый конец отрезка: ");
+ B = readDouble();
+ }
+
+ /**
+ * Метод, который считывает степень интерполяционного многочлена.
+ */
+ private static void readInterpolationPolDegree() {
+ System.out
+ .println(String.format("Введите степень интерполяционного многочлена N (N <= %d): ", M));
+ N = readInt();
+ while (N > M || N <= 0) {
+ System.out.println(String.format("Введите целое значение N: N >= 1, N <= %d: ", M));
+ N = readInt();
+ }
+ }
+
+ private static Double readDouble() {
+ String readValue = scanner.nextLine();
+ while (!isDoubleValue(readValue)) {
+ System.out.println("Пожалуйста, введите корректное значение (дробное или целое число).");
+ readValue = scanner.nextLine();
+ }
+
+ return Double.parseDouble(readValue);
+ }
+
+ /**
+ * Метод, который считывает из консоли число.
+ *
+ * @return - возвращает целое число
+ */
+ private static Integer readInt() {
+ String readValue = scanner.nextLine();
+ while (!isIntValue(readValue)) {
+ System.out.println("Пожалуйста, введите целое значение.");
+ readValue = scanner.nextLine();
+ }
+
+ return Integer.parseInt(readValue);
+ }
+
+ /**
+ * Метод, которые проверяет, является ли целым числом строка.
+ *
+ * @param value - исходная строка
+ * @return - true, если является целым числом, иначе false
+ */
+ private static boolean isIntValue(String value) {
+ try {
+ Integer.parseInt(value);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean isDoubleValue(String value) {
+ try {
+ Double.parseDouble(value);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * Метод, который печатает таблицу значений.
+ */
+ private static void printFuncTable(List table) {
+ String[][] convertedTable = new String[table.size() + 1][2];
+ convertedTable[0][0] = "xK";
+ convertedTable[0][1] = "f(xK)";
+
+ for (int i = 0; i < table.size(); i++) {
+ Double key = table.get(i).getValue();
+ Double value = table.get(i).getFunctionValue();
+ convertedTable[i + 1][0] = String.format("%.2f", key);
+ convertedTable[i + 1][1] = String.valueOf(value);
+
+ //System.out.println(String.format("x%d: %.2f, f(x%d): %.2f", i, key, i, value));
+ }
+
+ printer.print(convertedTable);
+ System.out.println(" ");
+ }
+
+ /**
+ * Метод, который печатает исходные параметры задачи.
+ */
+ private static void printInitialParams() {
+ System.out.println("");
+ System.out.println(String.format("Число значение в таблице: %d", M + 1));
+ System.out.println(String.format("Исходный промежуток: [%.2f; %.2f]", A, B));
+ }
+
+ /**
+ * Метод, который печатает описание лабораторной работы.
+ */
+ private static void printIntroduction() {
+ System.out.println("Лабораторная работа номер 2");
+ System.out.println("На тему: \"Численные методы решения нелинейных уравнений\".");
+ System.out.println("Работа выполнена студентом 343 группы СПбГУ Степыревом Даниилом");
+ System.out.println("Вариант 12.");
+ System.out.println("Функция, приближенное значение которой будет вычисляться: "
+ + "exp(-x) - x^2 / 2.");
+ System.out.println("\n");
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_2/NewtonCoef.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_2/NewtonCoef.java
new file mode 100644
index 00000000..08444663
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_2/NewtonCoef.java
@@ -0,0 +1,19 @@
+package group343.stepyrev.lab2_2;
+
+public class NewtonCoef {
+ private final Integer number;
+ private final Double value;
+
+ public NewtonCoef(Integer number, Double value) {
+ this.number = number;
+ this.value = value;
+ }
+
+ public Double getValue() {
+ return value;
+ }
+
+ public Integer getNumber() {
+ return number;
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_2/NewtonPolynomial.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_2/NewtonPolynomial.java
new file mode 100644
index 00000000..af014c31
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab2_2/NewtonPolynomial.java
@@ -0,0 +1,185 @@
+package group343.stepyrev.lab2_2;
+
+import group343.stepyrev.lab2_1.FunctionPoint;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Класс, который реализует интерполяионный многочлен Ньютона.
+ */
+public class NewtonPolynomial {
+
+ private final Integer M;
+ private final Double A;
+ private final Double B;
+
+ private Double X;
+ private Integer N;
+
+ private List functionPoints;
+ private List sortedPoints;
+ private Map> newtonCoefficients;
+
+ public NewtonPolynomial(Integer m, Double a, Double b) {
+ M = m;
+ A = a;
+ B = b;
+
+ functionPoints = initializeFunctionPoints();
+ newtonCoefficients = new HashMap<>();
+ }
+
+ public NewtonPolynomial(Integer m, List functionPoints) {
+ M = m;
+ A = 1D;
+ B = 2D;
+ this.functionPoints = functionPoints;
+ newtonCoefficients = new HashMap<>();
+ }
+
+ public List getFunctionPoints() {
+ return functionPoints;
+ }
+
+ public List getSortedPoints() {
+ return sortedPoints;
+ }
+
+ /**
+ * Метод, который заполняет таблицу значений.
+ *
+ * @return - таблицу значений
+ */
+ private List initializeFunctionPoints() {
+ List result = new LinkedList<>();
+
+ for (int j = 0; j <= M; j++) {
+ Double point = A + j * (B - A) / M;
+ Double funcValue = getFunctionValue(point);
+ result.add(new FunctionPoint(point, funcValue));
+ }
+
+ return result;
+ }
+
+ public List sortFunctionPoints(Double x, Integer n) {
+ X = x;
+ N = n;
+ sortedPoints = functionPoints;
+ for (FunctionPoint point : sortedPoints) {
+ point.setDistanceToPoint(x);
+ }
+
+ Comparator comparator = Comparator.comparing(FunctionPoint::getDistanceToPoint);
+ sortedPoints.sort(comparator);
+ sortedPoints = sortedPoints.subList(0, N + 1);
+ findNewtonCoefficients();
+
+ return sortedPoints;
+ }
+
+ private void findNewtonCoefficients() {
+ List coefficients = new LinkedList<>();
+ newtonCoefficients
+ .put(0,
+ Collections.singletonList(new NewtonCoef(0, sortedPoints.get(0).getFunctionValue())));
+
+ for (int degree = 1; degree < N + 1; degree++) {
+ for (int i = 0; i + degree < N + 1; i++) {
+ double elemValue = countNewtonCoefficient(i, i + degree);
+ coefficients.add(new NewtonCoef(i,
+ elemValue)); // первая координата точки - номер первого элемента, вторая - значения коэффициента
+ }
+ newtonCoefficients.put(degree, coefficients);
+
+ coefficients = new LinkedList<>();
+ }
+ }
+
+ private double countNewtonCoefficient(int fstNumber, int lastNumber) {
+ int degree = lastNumber - fstNumber;
+ double fstElem;
+ double sndElem;
+ double denominator;
+
+ if (degree == 1) {
+ fstElem = sortedPoints.get(lastNumber).getFunctionValue();
+ sndElem = sortedPoints.get(fstNumber).getFunctionValue();
+ denominator =
+ sortedPoints.get(lastNumber).getValue() - sortedPoints.get(fstNumber).getValue();
+ } else {
+ List thisDegreeCoefs = newtonCoefficients.get(degree - 1);
+
+ fstElem = getFunctionPointValue(thisDegreeCoefs, fstNumber + 1);
+ sndElem = getFunctionPointValue(thisDegreeCoefs, fstNumber);
+ denominator = sortedPoints.get(lastNumber).getValue() - sortedPoints.get(fstNumber).getValue();
+ }
+
+ return (fstElem - sndElem) / denominator;
+ }
+
+ private double getFunctionPointValue(List points, int index) {
+ for (NewtonCoef point : points) {
+ if (point.getNumber() == index) { // FIXME
+ return point.getValue();
+ }
+ }
+
+ return 0;
+ }
+
+ public Double getPolynomialValue() {
+ double result = 0D;
+
+ double aK;
+ double xComposition;
+ for (int k = 0; k < sortedPoints.size(); k++) {
+ aK = getNewtonCoefficient(k);
+ xComposition = getXComposition(k);
+ result += aK * xComposition;
+ }
+
+ return result;
+ }
+
+ public Double getPolynomialValue(double x) {
+ sortFunctionPoints(x, N);
+ return getPolynomialValue();
+ }
+
+ /**
+ * Метод, который вычисляет произведение иксов: (x - x0)(x - x1) ... (x - x(K-1))
+ *
+ * @param k - номер последнего x
+ * @return - произведение иксов
+ */
+ private double getXComposition(int k) {
+ double result = 1;
+ double xK;
+ for (int i = 0; i < k; i++) {
+ xK = sortedPoints.get(i).getValue();
+ result *= (X - xK);
+ }
+
+ return result;
+ }
+
+ private double getNewtonCoefficient(int k) {
+ return newtonCoefficients.get(k).get(0).getValue();
+ }
+
+ /**
+ * Метод, который возвращает значение исходной функции в точке.
+ *
+ * @param point - точка, в которой требуется найти значени
+ * @return - значение функции в точке
+ */
+ public double getFunctionValue(double point) {
+ return Math.exp(-point) - Math.pow(point, 2) / 2; // exp(-x) - x^2 / 2
+ }
+
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_1/Main.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_1/Main.java
new file mode 100644
index 00000000..3c4179b9
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_1/Main.java
@@ -0,0 +1,217 @@
+package group343.stepyrev.lab3_1;
+
+import group343.stepyrev.lab2_1.FunctionPoint;
+import group343.stepyrev.util.PrettyPrinter;
+import java.util.List;
+import java.util.Scanner;
+
+public class Main {
+
+ private static double A;
+ private static double B;
+ private static Integer M;
+ private static Integer N;
+ private static Double F;
+
+ private static Scanner scanner;
+ private static ReverseInterpolator interpolator;
+
+ private final static PrettyPrinter printer = new PrettyPrinter(System.out);
+
+ public static void main(String[] args) {
+ scanner = new Scanner(System.in);
+ printIntroduction();
+
+ readInitialParams();
+ printInitialParams();
+ interpolator = new ReverseInterpolator(M, A, B);
+
+ List funcTable = interpolator.getFunctionPoints();
+ System.out.println("Таблица значений: ");
+ printFuncTable(funcTable, false);
+
+ String answer = "yes";
+ while (answer.equals("yes")) {
+ doApproximation();
+
+ System.out
+ .println("Если хотите продолжить вычисления с новыми значениями x и n, введите yes.");
+ answer = scanner.nextLine();
+ }
+ }
+
+ private static void doApproximation() {
+ System.out.println("Введите точку интерполирования F: ");
+ F = readDouble();
+ readInterpolationPolDegree();
+
+ findRootByFirstMethod();
+ findRootBySecondMethod();
+ }
+
+ private static void findRootByFirstMethod() {
+ System.out.println("Нахождение решения первым методом.");
+
+ Double root = interpolator.findSolutionByReverseTable(F, N);
+ List sortedPoints = interpolator.getSortedPoints();
+
+ System.out.println(String
+ .format("Первые %d значений таблицы после сортировки относительно удаления от F (%.5f): ",
+ N + 1, F));
+ printFuncTable(sortedPoints, true);
+
+ System.out.println(
+ String.format("Значение X = Qn(%.3f): %.14f", F, root));
+
+ double polValue = interpolator.getFunctionValue(root);
+ Double difference = Math.abs(F - polValue);
+ System.out
+ .println(String.format("Модуль невязки: %.14f", difference));
+ System.out.println("");
+ }
+
+ private static void findRootBySecondMethod() {
+ System.out.println("Нахождение решения вторым методом.");
+
+ Double difference;
+ List roots = interpolator.findSolutionByRoot(F, N);
+ for (Double root : roots) {
+ System.out.println(
+ String.format("Значение X = Qn(%.3f): %.14f", F, root));
+
+ double polValue = interpolator.getFunctionValue(root);
+ difference = Math.abs(F - polValue);
+ System.out
+ .println(String.format("Модуль невязки: %.14f", difference));
+ }
+ }
+
+ /**
+ * Метод, в котором считываются исходные параметры задачи.
+ */
+ private static void readInitialParams() {
+ System.out.println("Введите число значений в таблице: ");
+ M = readInt() - 1;
+ while (M <= 0) {
+ System.out.println("Введите M >= 2.");
+ M = readInt() - 1;
+ }
+
+ System.out.println("Введите левый конец отрезка: ");
+ A = readDouble();
+
+ System.out.println("Введите правый конец отрезка: ");
+ B = readDouble();
+ }
+
+ /**
+ * Метод, который считывает степень интерполяционного многочлена.
+ */
+ private static void readInterpolationPolDegree() {
+ System.out
+ .println(String.format("Введите степень интерполяционного многочлена N (N <= %d): ", M));
+ N = readInt();
+ while (N > M || N <= 0) {
+ System.out.println(String.format("Введите целое значение N: N >= 1, N <= %d: ", M));
+ N = readInt();
+ }
+ }
+
+ private static Double readDouble() {
+ String readValue = scanner.nextLine();
+ while (!isDoubleValue(readValue)) {
+ System.out.println("Пожалуйста, введите корректное значение (дробное или целое число).");
+ readValue = scanner.nextLine();
+ }
+
+ return Double.parseDouble(readValue);
+ }
+
+ /**
+ * Метод, который считывает из консоли число.
+ *
+ * @return - возвращает целое число
+ */
+ private static Integer readInt() {
+ String readValue = scanner.nextLine();
+ while (!isIntValue(readValue)) {
+ System.out.println("Пожалуйста, введите целое значение.");
+ readValue = scanner.nextLine();
+ }
+
+ return Integer.parseInt(readValue);
+ }
+
+ /**
+ * Метод, которые проверяет, является ли целым числом строка.
+ *
+ * @param value - исходная строка
+ * @return - true, если является целым числом, иначе false
+ */
+ private static boolean isIntValue(String value) {
+ try {
+ Integer.parseInt(value);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean isDoubleValue(String value) {
+ try {
+ Double.parseDouble(value);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * Метод, который печатает таблицу значений.
+ */
+ private static void printFuncTable(List table, boolean isXFst) {
+ String[][] convertedTable = new String[table.size() + 1][2];
+
+ convertedTable[0][0] = "f(xK)";
+ convertedTable[0][1] = "xK";
+
+ for (int i = 0; i < table.size(); i++) {
+ Double key = table.get(i).getValue();
+ Double value = table.get(i).getFunctionValue();
+ if (isXFst) {
+ convertedTable[i + 1][0] = String.valueOf(key);
+ convertedTable[i + 1][1] = String.valueOf(value);
+ } else {
+ convertedTable[i + 1][0] = String.valueOf(value);
+ convertedTable[i + 1][1] = String.format("%.2f", key);
+ }
+
+ //System.out.println(String.format("x%d: %.2f, f(x%d): %.2f", i, key, i, value));
+ }
+
+ printer.print(convertedTable);
+ System.out.println(" ");
+ }
+
+ /**
+ * Метод, который печатает исходные параметры задачи.
+ */
+ private static void printInitialParams() {
+ System.out.println("");
+ System.out.println(String.format("Число значение в таблице: %d", M + 1));
+ System.out.println(String.format("Исходный промежуток: [%.2f; %.2f]", A, B));
+ }
+
+ /**
+ * Метод, который печатает описание лабораторной работы.
+ */
+ private static void printIntroduction() {
+ System.out.println("Лабораторная работа номер 3.1");
+ System.out.println("На тему: \"Задача обратного интерполирования\".");
+ System.out.println("Работа выполнена студентом 343 группы СПбГУ Степыревом Даниилом");
+ System.out.println("Вариант 12.");
+ System.out.println("Функция, приближенное значение обратной которой будет вычисляться: "
+ + "exp(-x) - x^2 / 2.");
+ System.out.println("\n");
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_1/ReverseInterpolator.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_1/ReverseInterpolator.java
new file mode 100644
index 00000000..e708868e
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_1/ReverseInterpolator.java
@@ -0,0 +1,117 @@
+package group343.stepyrev.lab3_1;
+
+import group343.stepyrev.util.RootFinder;
+import group343.stepyrev.util.Segment;
+import group343.stepyrev.lab2_1.FunctionPoint;
+import group343.stepyrev.lab2_2.NewtonPolynomial;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Класс, который решает задачу обратного интерполирования.
+ */
+public class ReverseInterpolator {
+
+ private final Integer M;
+ private final Double A;
+ private final Double B;
+ private final Double EPSILON;
+
+ private Double fX;
+ private Integer N;
+
+ private NewtonPolynomial polynomial;
+ private RootFinder rootFinder;
+
+ private List functionPoints;
+ private List reversedTable;
+
+ private Integer numberOfSegments = 1000;
+
+ public ReverseInterpolator(Integer m, Double a, Double b) {
+ M = m;
+ A = a;
+ B = b;
+ EPSILON = Math.pow(10, -12);
+
+ functionPoints = initializeFunctionPoints();
+ reversedTable = new LinkedList<>();
+ polynomial = new NewtonPolynomial(M, functionPoints);
+ }
+
+ public Double findSolutionByReverseTable(Double fx, int n) {
+ this.fX = fx;
+ this.N = n;
+
+ reverseTable();
+ polynomial = new NewtonPolynomial(M, reversedTable);
+ polynomial.sortFunctionPoints(fx, n);
+
+ return polynomial.getPolynomialValue();
+ }
+
+ private void reverseTable() {
+ reversedTable = new LinkedList<>();
+
+ for (FunctionPoint point : functionPoints) {
+ double value = point.getValue();
+ double functionValue = point.getFunctionValue();
+
+ reversedTable.add(new FunctionPoint(functionValue, value));
+ }
+ }
+
+ public List findSolutionByRoot(Double fx, int n) {
+ this.fX = fx;
+ this.N = n;
+
+ polynomial = new NewtonPolynomial(M, functionPoints);
+ polynomial.sortFunctionPoints(fx, n);
+ rootFinder = new RootFinder(A, B, EPSILON, polynomial, fx);
+
+ return getRoots();
+ }
+
+ public List getFunctionPoints() {
+ return functionPoints;
+ }
+
+ public List getSortedPoints() {
+ return polynomial.getSortedPoints();
+ }
+
+ private List getRoots() {
+ List roots = new LinkedList<>();
+ List segments = rootFinder.separateRoots(numberOfSegments);
+
+ List segmentRoots;
+ for (Segment segment : segments) {
+ segmentRoots = rootFinder.findRootByBisectionMethod(segment);
+ roots.addAll(segmentRoots);
+ }
+
+ return roots;
+ }
+
+ /**
+ * Метод, который заполняет таблицу значений.
+ *
+ * @return - таблицу значений
+ */
+ private List initializeFunctionPoints() {
+ List result = new LinkedList<>();
+
+ for (int j = 0; j <= M; j++) {
+ Double point = A + j * (B - A) / M;
+ Double funcValue = getFunctionValue(point);
+ result.add(new FunctionPoint(point, funcValue));
+ }
+
+ return result;
+ }
+
+ public Double getFunctionValue(Double point) {
+ return Math.exp(-point) - Math.pow(point, 2) / 2; // exp(-x) - x^2 / 2
+ }
+
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_2/DerivativeFinder.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_2/DerivativeFinder.java
new file mode 100644
index 00000000..dfc492e1
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_2/DerivativeFinder.java
@@ -0,0 +1,101 @@
+package group343.stepyrev.lab3_2;
+
+import group343.stepyrev.lab2_1.FunctionPoint;
+import java.util.LinkedList;
+import java.util.List;
+
+public class DerivativeFinder {
+
+ private Double A;
+ private Integer M;
+ private Double H;
+
+ private List points;
+
+ public DerivativeFinder(Double A, Integer M, Double H) {
+ this.A = A;
+ this.M = M;
+ this.H = H;
+
+ points = initializePoints(A, M, H);
+ }
+
+ public List getPointsList() {
+ return points;
+ }
+
+ private List initializePoints(Double a, Integer m, Double h) {
+ List pointList = new LinkedList<>();
+
+ for (int i = 0; i < m + 1; i++) {
+ double x = a + i * h;
+ double fX = getFunctionValue(x);
+ pointList.add(new FunctionPoint(x, fX));
+ }
+
+ return pointList;
+ }
+
+ public List getDerivativePackage() {
+ List packages = new LinkedList<>();
+
+ for (int i = 0; i < points.size(); i++) {
+ double x = points.get(i).getValue();
+ double fX = points.get(i).getFunctionValue();
+ double fstDer = countFstDerivative(i);
+ double sndDer = countSndDerivative(i);
+
+ double absoluteFstValue = getFstDer(x);
+ double absoluteSndValue = getSndDer(x);
+
+ double absFstDer = Math.abs(fstDer - absoluteFstValue);
+ double absSndDer = Math.abs(sndDer - absoluteSndValue);
+
+ DerivativePackage pack = new DerivativePackage(x, fX, fstDer, sndDer, absFstDer, absSndDer);
+ packages.add(pack);
+ }
+
+ return packages;
+ }
+
+ private double countFstDerivative(int n) {
+ if (n == 0) {
+ return
+ (-3 * points.get(n).getFunctionValue() + 4 * points.get(n + 1).getFunctionValue() - points
+ .get(n + 2).getFunctionValue())
+ / (2 * H);
+ }
+
+ if (n == points.size() - 1) {
+ return
+ (3 * points.get(n).getFunctionValue() - 4 * points.get(n - 1).getFunctionValue() + points
+ .get(n - 2).getFunctionValue())
+ / (2 * H);
+ }
+
+ return (points.get(n + 1).getFunctionValue() - points.get(n - 1).getFunctionValue()) / (2 * H);
+ }
+
+ private double countSndDerivative(int n) {
+ if (n == 0 || n == points.size() - 1) {
+ return 0;
+ }
+
+ return (points.get(n + 1).getFunctionValue() - 2 * points.get(n).getFunctionValue() + points
+ .get(n - 1).getFunctionValue()) / (H * H);
+ }
+
+
+ private double getFunctionValue(double x) {
+ return Math.exp(4.5 * x);
+ }
+
+ private double getFstDer(double x) {
+ return 4.5 * getFunctionValue(x);
+ }
+
+ private double getSndDer(double x) {
+ return 4.5 * 4.5 * getFunctionValue(x);
+ }
+
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_2/DerivativePackage.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_2/DerivativePackage.java
new file mode 100644
index 00000000..0ba166be
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_2/DerivativePackage.java
@@ -0,0 +1,61 @@
+package group343.stepyrev.lab3_2;
+
+/**
+ * A class that contains x, f(x), f'(x), f''(x)
+ */
+public class DerivativePackage {
+
+ private double x;
+ private double fX;
+ private double fstDerivative;
+ private double sndDerivative;
+
+ private double absFstDer;
+ private double absSndDer;
+
+ public DerivativePackage(double x, double fX, double fstDer, double sndDer, double absFstDer,
+ double absSndDer) {
+ this.x = x;
+ this.fX = fX;
+ this.fstDerivative = fstDer;
+ this.sndDerivative = sndDer;
+ this.absFstDer = absFstDer;
+ this.absSndDer = absSndDer;
+ }
+
+ public double getX() {
+ return x;
+ }
+
+ public double getfX() {
+ return fX;
+ }
+
+ public void setfX(double fX) {
+ this.fX = fX;
+ }
+
+ public double getFstDerivative() {
+ return fstDerivative;
+ }
+
+ public void setFstDerivative(double fstDerivative) {
+ this.fstDerivative = fstDerivative;
+ }
+
+ public double getSndDerivative() {
+ return sndDerivative;
+ }
+
+ public void setSndDerivative(double sndDerivative) {
+ this.sndDerivative = sndDerivative;
+ }
+
+ public double getAbsFstDer() {
+ return absFstDer;
+ }
+
+ public double getAbsSndDer() {
+ return absSndDer;
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_2/Main.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_2/Main.java
new file mode 100644
index 00000000..4e39c0ca
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/lab3_2/Main.java
@@ -0,0 +1,201 @@
+package group343.stepyrev.lab3_2;
+
+import group343.stepyrev.lab2_1.FunctionPoint;
+import group343.stepyrev.util.PrettyPrinter;
+import java.util.List;
+import java.util.Scanner;
+
+public class Main {
+
+ private static double A;
+ private static Integer M;
+ private static Double H;
+
+ private static Scanner scanner;
+ private static DerivativeFinder finder;
+
+ private final static PrettyPrinter printer = new PrettyPrinter(System.out);
+
+ public static void main(String[] args) {
+ scanner = new Scanner(System.in);
+ printIntroduction();
+
+ String answer = "yes";
+ while (answer.equals("yes")) {
+ doApproximation();
+
+ System.out
+ .println("Если хотите продолжить вычисления с новыми значениями M, A, H, введите yes.");
+ answer = scanner.nextLine();
+ }
+ }
+
+ private static void doApproximation() {
+ readInitialParams();
+ printInitialParams();
+ finder = new DerivativeFinder(A, M, H);
+
+ List funcTable = finder.getPointsList();
+ System.out.println("Таблица значений: ");
+ printFuncTable(funcTable);
+
+ List packages = finder.getDerivativePackage();
+ printPackageTable(packages);
+ }
+
+ /**
+ * Метод, в котором считываются исходные параметры задачи.
+ */
+ private static void readInitialParams() {
+ System.out.println("Введите число значений в таблице: ");
+ M = readInt() - 1;
+ while (M <= 0) {
+ System.out.println("Введите M >= 2.");
+ M = readInt() - 1;
+ }
+
+ System.out.println("Введите левый конец отрезка: ");
+ A = readDouble();
+
+ System.out.println("Введите значение сдвига h > 0: ");
+ H = readDouble();
+ while (H <= 0) {
+ System.out.println("Введите h > 0");
+ H = readDouble();
+ }
+ }
+
+
+ private static Double readDouble() {
+ String readValue = scanner.nextLine();
+ while (!isDoubleValue(readValue)) {
+ System.out.println("Пожалуйста, введите корректное значение (дробное или целое число).");
+ readValue = scanner.nextLine();
+ }
+
+ return Double.parseDouble(readValue);
+ }
+
+ /**
+ * Метод, который считывает из консоли число.
+ *
+ * @return - возвращает целое число
+ */
+ private static Integer readInt() {
+ String readValue = scanner.nextLine();
+ while (!isIntValue(readValue)) {
+ System.out.println("Пожалуйста, введите целое значение.");
+ readValue = scanner.nextLine();
+ }
+
+ return Integer.parseInt(readValue);
+ }
+
+ /**
+ * Метод, которые проверяет, является ли целым числом строка.
+ *
+ * @param value - исходная строка
+ * @return - true, если является целым числом, иначе false
+ */
+ private static boolean isIntValue(String value) {
+ try {
+ Integer.parseInt(value);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean isDoubleValue(String value) {
+ try {
+ Double.parseDouble(value);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * Метод, который печатает таблицу значений.
+ */
+ private static void printFuncTable(List table) {
+ String[][] convertedTable = new String[table.size() + 1][2];
+
+ convertedTable[0][0] = "xK";
+ convertedTable[0][1] = "f(xK)";
+
+ for (int i = 0; i < table.size(); i++) {
+ Double key = table.get(i).getValue();
+ Double value = table.get(i).getFunctionValue();
+ convertedTable[i + 1][0] = String.format("%.4f", key);
+ convertedTable[i + 1][1] = String.valueOf(value);
+
+ //System.out.println(String.format("x%d: %.2f, f(x%d): %.2f", i, key, i, value));
+ }
+
+ printer.print(convertedTable);
+ System.out.println(" ");
+ }
+
+ private static void printPackageTable(List packages) {
+ String[][] outTable = new String[packages.size() + 1][6];
+ outTable[0][0] = "xI";
+ outTable[0][1] = "f(xI)";
+ outTable[0][2] = "f'(xI)чд";
+ outTable[0][3] = " |f'(xI)т - f'(xI)чд| ";
+ outTable[0][4] = "f''(xI)чд";
+ outTable[0][5] = " |f''(xI)т - f''(xI)чд| ";
+
+ for (int i = 0; i < packages.size(); i++) {
+ DerivativePackage derivativePackage = packages.get(i);
+
+ double x = derivativePackage.getX();
+ double fX = derivativePackage.getfX();
+ double fstDer = derivativePackage.getFstDerivative();
+ double sndDer = derivativePackage.getSndDerivative();
+ double absFstDer = derivativePackage.getAbsFstDer();
+ double absSndDer = derivativePackage.getAbsSndDer();
+
+ outTable[i + 1][0] = String.format("%f", x);
+ outTable[i + 1][1] = String.valueOf(fX);
+ outTable[i + 1][2] = String.valueOf(fstDer);
+ outTable[i + 1][3] = String.valueOf(absFstDer);
+
+ if (i == 0 || i == (packages.size() - 1)) {
+ outTable[i + 1][4] = "";
+ outTable[i + 1][5] = "";
+ continue;
+ }
+
+ outTable[i + 1][4] = String.valueOf(sndDer);
+ outTable[i + 1][5] = String.valueOf(absSndDer);
+ }
+
+ printer.print(outTable);
+ System.out.println(" ");
+ }
+
+ /**
+ * Метод, который печатает исходные параметры задачи.
+ */
+ private static void printInitialParams() {
+ System.out.println("");
+ System.out.println(String.format("Число значение в таблице: %d", M + 1));
+ System.out.println(String.format("Начальная точка A: %.2f", A));
+ System.out.println(String.format("Сдвиг h: %f", H));
+ }
+
+ /**
+ * Метод, который печатает описание лабораторной работы.
+ */
+ private static void printIntroduction() {
+ System.out.println("Лабораторная работа номер 3.1");
+ System.out.println("На тему: \"Нахождение производных таблично-заданной функции\n"
+ + "по формулам численного дифференцирования\".");
+ System.out.println("Работа выполнена студентом 343 группы СПбГУ Степыревом Даниилом");
+ System.out.println("Вариант 12.");
+ System.out.println("Функция, приближенное значение обратной которой будет вычисляться: "
+ + "exp(4.5 * x)");
+ System.out.println("\n");
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/util/PrettyPrinter.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/util/PrettyPrinter.java
new file mode 100644
index 00000000..81c2e22b
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/util/PrettyPrinter.java
@@ -0,0 +1,113 @@
+package group343.stepyrev.util;
+
+import static java.lang.String.format;
+
+import java.io.PrintStream;
+
+public final class PrettyPrinter {
+
+ private static final char BORDER_KNOT = '+';
+ private static final char HORIZONTAL_BORDER = '-';
+ private static final char VERTICAL_BORDER = '|';
+
+ private static final String DEFAULT_AS_NULL = "(NULL)";
+
+ private final PrintStream out;
+ private final String asNull;
+
+ public PrettyPrinter(PrintStream out) {
+ this(out, DEFAULT_AS_NULL);
+ }
+
+ public PrettyPrinter(PrintStream out, String asNull) {
+ if ( out == null ) {
+ throw new IllegalArgumentException("No print stream provided");
+ }
+ if ( asNull == null ) {
+ throw new IllegalArgumentException("No NULL-value placeholder provided");
+ }
+ this.out = out;
+ this.asNull = asNull;
+ }
+
+ public void print(String[][] table) {
+ if ( table == null ) {
+ throw new IllegalArgumentException("No tabular data provided");
+ }
+ if ( table.length == 0 ) {
+ return;
+ }
+ final int[] widths = new int[getMaxColumns(table)];
+ adjustColumnWidths(table, widths);
+ printPreparedTable(table, widths, getHorizontalBorder(widths));
+ }
+
+ private void printPreparedTable(String[][] table, int widths[], String horizontalBorder) {
+ final int lineLength = horizontalBorder.length();
+ out.println(horizontalBorder);
+ for ( final String[] row : table ) {
+ if ( row != null ) {
+ out.println(getRow(row, widths, lineLength));
+ out.println(horizontalBorder);
+ }
+ }
+ }
+
+ private String getRow(String[] row, int[] widths, int lineLength) {
+ final StringBuilder builder = new StringBuilder(lineLength).append(VERTICAL_BORDER);
+ final int maxWidths = widths.length;
+ for ( int i = 0; i < maxWidths; i++ ) {
+ builder.append(padRight(getCellValue(safeGet(row, i, null)), widths[i])).append(VERTICAL_BORDER);
+ }
+ return builder.toString();
+ }
+
+ private String getHorizontalBorder(int[] widths) {
+ final StringBuilder builder = new StringBuilder(256);
+ builder.append(BORDER_KNOT);
+ for ( final int w : widths ) {
+ for ( int i = 0; i < w; i++ ) {
+ builder.append(HORIZONTAL_BORDER);
+ }
+ builder.append(BORDER_KNOT);
+ }
+ return builder.toString();
+ }
+
+ private int getMaxColumns(String[][] rows) {
+ int max = 0;
+ for ( final String[] row : rows ) {
+ if ( row != null && row.length > max ) {
+ max = row.length;
+ }
+ }
+ return max;
+ }
+
+ private void adjustColumnWidths(String[][] rows, int[] widths) {
+ for ( final String[] row : rows ) {
+ if ( row != null ) {
+ for ( int c = 0; c < widths.length; c++ ) {
+ final String cv = getCellValue(safeGet(row, c, asNull));
+ final int l = cv.length();
+ if ( widths[c] < l ) {
+ widths[c] = l;
+ }
+ }
+ }
+ }
+ }
+
+ private static String padRight(String s, int n) {
+ return format("%1$-" + n + "s", s);
+ }
+
+ private static String safeGet(String[] array, int index, String defaultValue) {
+ return index < array.length ? array[index] : defaultValue;
+ }
+
+ private String getCellValue(Object value) {
+ return value == null ? asNull : value.toString();
+ }
+
+}
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/util/RootFinder.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/util/RootFinder.java
new file mode 100644
index 00000000..f8f57ce8
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/util/RootFinder.java
@@ -0,0 +1,89 @@
+package group343.stepyrev.util;
+
+import group343.stepyrev.lab2_2.NewtonPolynomial;
+import java.util.*;
+
+import static java.lang.Math.abs;
+
+/**
+ * Класс, который находит все корни нечетной кратности на заданном отрезке.
+ */
+public class RootFinder {
+
+ private double A;
+ private double B;
+ private double EPSILON;
+ private Segment taskSegment;
+
+ private NewtonPolynomial polynomial;
+
+ private Double FX;
+
+ public RootFinder(double A, double B, double EPSILON, NewtonPolynomial polynomial, Double fx) {
+ this.polynomial = polynomial;
+ this.A = A;
+ this.B = B;
+ this.EPSILON = EPSILON;
+ this.FX = fx;
+ this.taskSegment = new Segment(A, B);
+ }
+
+
+ /**
+ * Метод, который отделяет корни.
+ */
+ public List separateRoots(int n) {
+ double SHIFT = (B - A) / n; // это h
+ double currentStartPoint = taskSegment.getStartPoint(); // это x1
+ double currentEndPoint = currentStartPoint + SHIFT; // это x2
+ double startPointFunctionValue = getFunctionValue(currentStartPoint); // это y1
+
+ List segments = new LinkedList();
+ while (currentEndPoint <= taskSegment.getEndPoint()) {
+ double endPointFunctionValue = getFunctionValue(currentEndPoint); // это y2
+
+ if (startPointFunctionValue * endPointFunctionValue <= 0) {
+ Segment newSegment = new Segment(currentStartPoint, currentEndPoint);
+ segments.add(newSegment);
+ }
+
+ currentStartPoint = currentEndPoint;
+ currentEndPoint += SHIFT;
+ startPointFunctionValue = endPointFunctionValue;
+ }
+
+ return segments;
+ }
+
+ /**
+ * Метод, который уточняет корни на заданном отрезке методом бисекции (половинного деления).
+ *
+ * @param segment - это отрезок, на котором уточняется корень
+ */
+ public List findRootByBisectionMethod(Segment segment) {
+ double startPoint = segment.getStartPoint();
+ double endPoint = segment.getEndPoint();
+
+ List resultValues = new LinkedList<>();
+ double root = (startPoint + endPoint) / 2; // это Х
+ System.out.println(String.format("Начальное приближение к корню (x0): %.8f", root));
+ while ((endPoint - startPoint) > EPSILON) {
+ double middlePoint = (startPoint + endPoint) / 2; // это c
+
+ if (getFunctionValue(startPoint) * getFunctionValue(middlePoint) <= 0) {
+ endPoint = middlePoint;
+ } else {
+ startPoint = middlePoint;
+ }
+ }
+
+ root = (endPoint + startPoint) / 2;
+ resultValues.add(root);
+
+ return resultValues;
+ }
+
+ private Double getFunctionValue(double point) {
+ return polynomial.getPolynomialValue(point) - FX;
+ }
+}
\ No newline at end of file
diff --git a/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/util/Segment.java b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/util/Segment.java
new file mode 100644
index 00000000..377c3d42
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/main/java/group343/stepyrev/util/Segment.java
@@ -0,0 +1,30 @@
+package group343.stepyrev.util;
+
+/** Класс, реализующий отрезок. */
+public class Segment {
+ private double startPoint;
+ private double endPoint;
+
+ public Segment() {}
+
+ public Segment(double startPoint, double endPoint) {
+ this.startPoint = startPoint;
+ this.endPoint = endPoint;
+ }
+
+ public double getStartPoint() {
+ return startPoint;
+ }
+
+ public void setStartPoint(double startPoint) {
+ this.startPoint = startPoint;
+ }
+
+ public double getEndPoint() {
+ return endPoint;
+ }
+
+ public void setEndPoint(double endPoint) {
+ this.endPoint = endPoint;
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/test/java/LagrangePolynomialTest.java b/sem5/math-calculations/lab3/src/test/java/LagrangePolynomialTest.java
new file mode 100644
index 00000000..4eec2a88
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/test/java/LagrangePolynomialTest.java
@@ -0,0 +1,57 @@
+import group343.stepyrev.lab.LagrangePolynomial;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class LagrangePolynomialTest {
+ @Test
+ public void lowDegreePolynomialTest() {
+ Integer m = 100;
+ Double a = 1D;
+ Double b = 2D;
+ LagrangePolynomial polynomial = new LowDegreePolynomial(m, a, b);
+
+ Integer n = 5;
+ double x = a;
+ double funcValue;
+ double polValue;
+ double shift = (b - a) / 10;
+ for (int i = 0; i < 10; i++) {
+ funcValue = polynomial.getFunctionValue(x);
+ polynomial.sortFunctionPoints(x, n);
+ polValue = polynomial.getPolynomialValue();
+ Assert.assertEquals(polValue, funcValue, Math.pow(1, -20));
+
+ x += shift;
+ }
+ }
+
+ @Test
+ public void pointFromSegment() {
+ Integer m = 100;
+ Double a = 1D;
+ Double b = 5D;
+ Double x = a;
+ LagrangePolynomial polynomial = new LagrangePolynomial(m, a, b);
+
+ double funcValue;
+ double polValue;
+ for (int n = 1; n < 50; n++) {
+ funcValue = polynomial.getFunctionValue(x);
+ polynomial.sortFunctionPoints(x, n);
+ polValue = polynomial.getPolynomialValue();
+ Assert.assertEquals(polValue, funcValue, Math.pow(1, -20));
+ }
+ }
+
+ private class LowDegreePolynomial extends LagrangePolynomial {
+
+ public LowDegreePolynomial(Integer m, Double a, Double b) {
+ super(m, a, b);
+ }
+
+ @Override
+ public double getFunctionValue(double point) {
+ return Math.pow(point - 1, 2) + point + 1; // (x - 1) ^ 2 + x + 1
+ }
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/test/java/lab2_1/LagrangePolynomialTest.java b/sem5/math-calculations/lab3/src/test/java/lab2_1/LagrangePolynomialTest.java
new file mode 100644
index 00000000..eced4c3f
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/test/java/lab2_1/LagrangePolynomialTest.java
@@ -0,0 +1,59 @@
+package lab2_1;
+
+import group343.stepyrev.lab2_1.LagrangePolynomial;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class LagrangePolynomialTest {
+ @Test
+ public void lowDegreePolynomialTest() {
+ Integer m = 100;
+ Double a = 1D;
+ Double b = 2D;
+ LagrangePolynomial polynomial = new LowDegreePolynomial(m, a, b);
+
+ Integer n = 5;
+ double x = a;
+ double funcValue;
+ double polValue;
+ double shift = (b - a) / 10;
+ for (int i = 0; i < 10; i++) {
+ funcValue = polynomial.getFunctionValue(x);
+ polynomial.sortFunctionPoints(x, n);
+ polValue = polynomial.getPolynomialValue();
+ Assert.assertEquals(polValue, funcValue, Math.pow(1, -20));
+
+ x += shift;
+ }
+ }
+
+ @Test
+ public void pointFromSegment() {
+ Integer m = 100;
+ Double a = 1D;
+ Double b = 5D;
+ Double x = a;
+ LagrangePolynomial polynomial = new LagrangePolynomial(m, a, b);
+
+ double funcValue;
+ double polValue;
+ for (int n = 1; n < 50; n++) {
+ funcValue = polynomial.getFunctionValue(x);
+ polynomial.sortFunctionPoints(x, n);
+ polValue = polynomial.getPolynomialValue();
+ Assert.assertEquals(polValue, funcValue, Math.pow(1, -20));
+ }
+ }
+
+ private class LowDegreePolynomial extends LagrangePolynomial {
+
+ public LowDegreePolynomial(Integer m, Double a, Double b) {
+ super(m, a, b);
+ }
+
+ @Override
+ public double getFunctionValue(double point) {
+ return Math.pow(point - 1, 2) + point + 1; // (x - 1) ^ 2 + x + 1
+ }
+ }
+}
diff --git a/sem5/math-calculations/lab3/src/test/java/lab2_2/NewtonPolynomialTest.java b/sem5/math-calculations/lab3/src/test/java/lab2_2/NewtonPolynomialTest.java
new file mode 100644
index 00000000..c13d3392
--- /dev/null
+++ b/sem5/math-calculations/lab3/src/test/java/lab2_2/NewtonPolynomialTest.java
@@ -0,0 +1,60 @@
+package lab2_2;
+
+import group343.stepyrev.lab2_2.NewtonPolynomial;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class NewtonPolynomialTest {
+ @Test
+ public void lowDegreePolynomialTest() {
+ Integer m = 100;
+ Double a = 1D;
+ Double b = 2D;
+ NewtonPolynomial polynomial = new LowDegreePolynomial(m, a, b);
+
+ Integer n = 5;
+ double x = a;
+ double funcValue;
+ double polValue;
+ double shift = (b - a) / 10;
+ for (int i = 0; i < 10; i++) {
+ funcValue = polynomial.getFunctionValue(x);
+ polynomial.sortFunctionPoints(x, n);
+ polValue = polynomial.getPolynomialValue();
+ Assert.assertEquals(polValue, funcValue, Math.pow(1, -20));
+
+ x += shift;
+ }
+ }
+
+ @Test
+ public void pointFromSegment() {
+ Integer m = 100;
+ Double a = 1D;
+ Double b = 5D;
+ Double x = a;
+ NewtonPolynomial polynomial = new NewtonPolynomial(m, a, b);
+
+ double funcValue;
+ double polValue;
+ for (int n = 1; n < 50; n++) {
+ funcValue = polynomial.getFunctionValue(x);
+ polynomial.sortFunctionPoints(x, n);
+ polValue = polynomial.getPolynomialValue();
+ Assert.assertEquals(polValue, funcValue, Math.pow(1, -20));
+ }
+ }
+
+ private class LowDegreePolynomial extends NewtonPolynomial {
+
+ public LowDegreePolynomial(Integer m, Double a, Double b) {
+ super(m, a, b);
+ }
+
+ @Override
+ public double getFunctionValue(double point) {
+ return Math.pow(point - 1, 2) + point + 1; // (x - 1) ^ 2 + x + 1
+ }
+ }
+}
+
diff --git a/sem5/math-calculations/lab3/target/classes/META-INF/secondLaboratory.kotlin_module b/sem5/math-calculations/lab3/target/classes/META-INF/secondLaboratory.kotlin_module
new file mode 100644
index 00000000..8fb60192
Binary files /dev/null and b/sem5/math-calculations/lab3/target/classes/META-INF/secondLaboratory.kotlin_module differ
diff --git a/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab/FunctionPoint.class b/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab/FunctionPoint.class
new file mode 100644
index 00000000..b72a6a82
Binary files /dev/null and b/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab/FunctionPoint.class differ
diff --git a/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab/LagrangePolynomial.class b/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab/LagrangePolynomial.class
new file mode 100644
index 00000000..b8b43f99
Binary files /dev/null and b/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab/LagrangePolynomial.class differ
diff --git a/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab/Main.class b/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab/Main.class
new file mode 100644
index 00000000..936f739a
Binary files /dev/null and b/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab/Main.class differ
diff --git a/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab2/Main.class b/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab2/Main.class
new file mode 100644
index 00000000..ba320ad4
Binary files /dev/null and b/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab2/Main.class differ
diff --git a/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab2/NewtonCoef.class b/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab2/NewtonCoef.class
new file mode 100644
index 00000000..76efd520
Binary files /dev/null and b/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab2/NewtonCoef.class differ
diff --git a/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab2/NewtonPolynomial.class b/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab2/NewtonPolynomial.class
new file mode 100644
index 00000000..6f735b7b
Binary files /dev/null and b/sem5/math-calculations/lab3/target/classes/group343/stepyrev/lab2/NewtonPolynomial.class differ
diff --git a/sem5/math-calculations/lab3/target/classes/group343/stepyrev/util/PrettyPrinter.class b/sem5/math-calculations/lab3/target/classes/group343/stepyrev/util/PrettyPrinter.class
new file mode 100644
index 00000000..9304e18f
Binary files /dev/null and b/sem5/math-calculations/lab3/target/classes/group343/stepyrev/util/PrettyPrinter.class differ
diff --git a/sem5/math-calculations/lab3/target/test-classes/LagrangePolynomialTest$LowDegreePolynomial.class b/sem5/math-calculations/lab3/target/test-classes/LagrangePolynomialTest$LowDegreePolynomial.class
new file mode 100644
index 00000000..8422ee26
Binary files /dev/null and b/sem5/math-calculations/lab3/target/test-classes/LagrangePolynomialTest$LowDegreePolynomial.class differ
diff --git a/sem5/math-calculations/lab3/target/test-classes/LagrangePolynomialTest.class b/sem5/math-calculations/lab3/target/test-classes/LagrangePolynomialTest.class
new file mode 100644
index 00000000..d6fe0cfd
Binary files /dev/null and b/sem5/math-calculations/lab3/target/test-classes/LagrangePolynomialTest.class differ
diff --git a/sem5/math-calculations/lab3/target/test-classes/META-INF/secondLaboratory.kotlin_module b/sem5/math-calculations/lab3/target/test-classes/META-INF/secondLaboratory.kotlin_module
new file mode 100644
index 00000000..8fb60192
Binary files /dev/null and b/sem5/math-calculations/lab3/target/test-classes/META-INF/secondLaboratory.kotlin_module differ